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

Web API not receiving the json of serialized object

客户端代码:

        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();
    }

网络API:

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

        return Json(result);
    }

用户模型

[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; }
}

没有数据到达 ValidateLogin,即使我用邮递员传递参数也是如此。

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

解决方案 1

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

解决方案 2

在客户端序列化数据时,使用 json 序列化行为,就像 Web API

var serializedData = JsonConvert.SerializeObject(data, new JsonSerializerSettings
{
    ContractResolver = new DefaultContractResolver
    {
        IgnoreSerializableAttribute = false
    }
});

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

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

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

    public string Password { get; set; }
}

给出以下结果

{
  "Username": "name",
  "Password": "pass"
}

但是当class被[Serializable]属性标记并且IgnoreSerializableAttribute设置为false时,所有私有和public字段被序列化,结果如下

{
  "<Username>k__BackingField": "name",
  "<Password>k__BackingField": "pass"
}

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