Web API复杂参数属性均为null

Edd*_*die 38 c# ajax jquery json asp.net-web-api

我有一个Web API服务调用,用于更新用户的首选项.不幸的是,当我从jQuery ajax调用调用此POST方法时,请求参数对象的属性始终为null(或默认值),而不是传入的内容.如果我使用REST客户端调用相同的方法(我使用Postman) ,它工作得很漂亮.我无法弄清楚我做错了什么,但希望有人见过这个.这很简单......

这是我的请求对象:

public class PreferenceRequest
{
    [Required]
    public int UserId;

    public bool usePopups;
    public bool useTheme;
    public int recentCount;
    public string[] detailsSections;
}
Run Code Online (Sandbox Code Playgroud)

这是UserController类中的控制器方法:

    public HttpResponseMessage Post([FromBody]PreferenceRequest request)
    {
        if (request.systemsUserId > 0)
        {
            TheRepository.UpdateUserPreferences(request.UserId, request.usePopups, request.useTheme,
                                         request.recentCount, request.detailsSections);

            return Request.CreateResponse(HttpStatusCode.OK, "Preferences Updated");                
        }
        else
        {
            return Request.CreateErrorResponse(HttpStatusCode.NotAcceptable, "You must provide User ID");
        }
    }
Run Code Online (Sandbox Code Playgroud)

这是我的ajax电话:

var request = {
    UserId: userId,
    usePopups: usePopups,
    useTheme: useTheme,
    recentCount: recentCount,
    detailsSections: details
};

$.ajax({
    type: "POST",
    data: request,
    url: "http://localhost:1111/service/User",
    success: function (data) {
        return callback(data);
    },
    error: function (error, statusText) {
        return callback(error);
    }
});
Run Code Online (Sandbox Code Playgroud)

我已经尝试将dataType和contentType设置为几个不同的东西('json','application/json'等),但请求对象的属性总是默认为null或null.所以,例如,如果我传入这个对象:

var request = {
  UserId: 58576,
  usePopups: false,
  useTheme: true,
  recentCount: 10,
  detailsSections: ['addresses', 'aliases', 'arrests', 'events', 'classifications', 'custody', 'identifiers', 'phone', 'remarks', 'watches']
}
Run Code Online (Sandbox Code Playgroud)

我可以看到一个完全填充的请求对象,其中包含上面列出的有效值.但是在Web API控制器中,请求存在,但属性如下:

  UserId: 0,
  usePopups: false,
  useTheme: false,
  recentCount: 0,
  detailsSections: null
Run Code Online (Sandbox Code Playgroud)

仅供参考 - 我没有在这个项目中使用任何ASP.Net MVC或ASP.NET页面,只是使用Web API作为服务并使用jQuery $ .ajax进行所有调用.

知道我在这里做错了吗?谢谢!

更新:我只想注意我在其他控制器中的同一个Web API项目中有很多方法可以完成同样的操作,而且我的调用完全相同,而且它们完美无缺!我花了一个上午比较各种调用,并且方法或标题似乎没有任何区别,但它只是不适用于这个特定的方法.

我也试过切换到Put方法,但是得到了完全相同的结果 - 请求对象进来了,但没有填充正确的值.令人沮丧的是,我在这个项目中有大约20个控制器类,而帖子在所有这些中工作......

blo*_*ish 55

这似乎是Asp.Net WebAPI的常见问题.
通常,null对象的原因是将json对象反序列化为C#对象.不幸的是,调试非常困难 - 因此找到问题所在.
我更喜欢将完整的json作为对象发送,然后手动反序列化.至少这样你会得到真正的错误而不是空值.
如果更改方法签名以接受对象,则使用JsonConvert:

public HttpResponseMessage Post(Object model)
        {
            var jsonString = model.ToString();
            PreferenceRequest result = JsonConvert.DeserializeObject<PreferenceRequest>(jsonString);
        }
Run Code Online (Sandbox Code Playgroud)

  • Sheesh ......这似乎是REST框架的基本功能.Web API如何才能做到这一点?无论如何,谢谢你的解决方法! (9认同)
  • 这非常适合作为调试的临时解决方法.修复序列化问题后,可以安全地再次删除变通方法. (6认同)
  • 抱歉,但是我无法使它正常工作。对象是System.Object,ToString产生“ System.Object”,并且JsonConvert崩溃。我想念什么吗??? (2认同)

baH*_*aHI 14

所以有 3 个可能的问题,我知道值没有绑定的地方:

  1. 没有公共参数构造函数
  2. 属性不是公共可设置的
  3. 存在绑定错误,导致 ModelState.Valid == false - 典型问题是:不兼容的值类型(json 对象到字符串、非 GUID 等)

所以我在考虑 API 调用是否应该应用一个过滤器,如果绑定导致错误,它会返回一个错误!


Sim*_*mon 12

也许它会有所帮助,我遇到了同样的问题.

一切都运作良好,突然之间,每个属性都是默认的.

经过一些快速测试后,我发现导致问题的是[Serializable]:

public IHttpActionResult Post(MyComplexClass myTaskObject)
{
    //MyTaskObject is not null, but every member are (the constructor get called).
}
Run Code Online (Sandbox Code Playgroud)

这是我班级的片段:

[Serializable]  <-- have to remove that [if it was added for any reason..]
public class MyComplexClass()
{
     public MyComplexClass ()
     {
        ..initiate my variables..
     }

     public string blabla {get;set;}
     public int intTest {get;set;
}
Run Code Online (Sandbox Code Playgroud)