Web API 未收到序列化对象的 json

mag*_*uri 2 c# asp.net asp.net-mvc asp.net-web-api asp.net-web-api2

客户端代码:

        public async Task<ActionResult> Login(UserLoginModel user)
    {
        UserModel data = new UserModel
        {
            Username = user.Username,
            Password = user.Password.GenerateHash()
        };

        var serializedData = JsonConvert.SerializeObject(data);

        var url = "http://localhost:55042/api/Login";

        var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
        httpWebRequest.ContentType = "application/json";
        httpWebRequest.Method = "POST";
        httpWebRequest.Accept = "application/json";

        using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
        {
            streamWriter.Write(serializedData);
            streamWriter.Flush();
            streamWriter.Close();
        }

        bool deserializedResult = false;
        using (var response = httpWebRequest.GetResponse() as HttpWebResponse)
        {
            if (httpWebRequest.HaveResponse && response != null) {
                using (var streamReader = new StreamReader(response.GetResponseStream())) {
                    var result = streamReader.ReadToEnd();
                    deserializedResult = JsonConvert.DeserializeObject<bool>(result);
                }
            }
        }

        return deserializedResult ? View() : throw new NotImplementedException();
    }
Run Code Online (Sandbox Code Playgroud)

网络API:

    [HttpPost]
    [Route("api/Login")]
    public IHttpActionResult ValidateLogin([FromBody]UserModel user)
    {
        var result = _service.FetchUser(user);

        return Json(result);
    }
Run Code Online (Sandbox Code Playgroud)

用户模型

[Serializable]
public class UserModel
{
    public int? ID { get; set; }

    public string Username { get; set; }

    public string Password { get; set; }

    public string Firstname { get; set; }

    public string Lastname { get; set; }

    public string Email { get; set; }

    public string NumberI { get; set; }

    public string NumberII { get; set; }

    public DateTime? CreateDate { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

即使我向邮递员传递参数,也没有数据到达 ValidateLogin。

我搜索了很多,根本找不到解决方案,尝试了所有代码片段,理解了它们然后又回来了等等,我被卡住了,有什么问题?

Ale*_*der 6

解决方案1

只需[Serializable]从中删除属性UserModel,一切都会正常工作。

解决方案2

当客户端使用JSON序列化行为序列化数据,Web API

var serializedData = JsonConvert.SerializeObject(data, new JsonSerializerSettings
{
    ContractResolver = new DefaultContractResolver
    {
        IgnoreSerializableAttribute = false
    }
});
Run Code Online (Sandbox Code Playgroud)

现在Web API将正确反序列化传递的模型。

发生这种情况是因为从某个版本开始Json.NET考虑对象是否标记为Serializable. 默认情况下,如果没有该属性,所有公共成员(属性和字段)都会被序列化。以下类的序列化

public class UserModel
{
    public string Username { get; set; }

    public string Password { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

给出以下结果

{
  "Username": "name",
  "Password": "pass"
}
Run Code Online (Sandbox Code Playgroud)

但是当类由[Serializable]属性标记并且IgnoreSerializableAttribute设置是false所有私有和公共字段被序列化并且结果如下

{
  "<Username>k__BackingField": "name",
  "<Password>k__BackingField": "pass"
}
Run Code Online (Sandbox Code Playgroud)

默认情况下,串行忽略[Serializable]属性,但在Web APIIgnoreSerializableAttribute被设置为false。所以现在很容易理解为什么服务器无法正确反序列化您的案例中的给定模型。