Web API не получает json сериализованного объекта - PullRequest
2 голосов
/ 27 марта 2019

код на стороне клиента:

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

В ValidateLogin не поступает никаких данных, даже когда я передаю параметры почтальону.

Iискал много , не нашел решения вообще, перепробовал все фрагменты кода, понял их, потом вернулся и так далее, я застрял, что не так?

1 Ответ

4 голосов
/ 28 марта 2019

Решение 1

Просто удалите атрибут [Serializable] из UserModel, и все будет работать нормально.

Решение 2

При сериализации данных на клиенте используйте поведение сериализации json, как Web API делает

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

Теперь Web API будет правильно десериализовать переданную модель.

Это происходит из-за запуска с некоторой версии Json.NET считает, что объект помечен как Serializable.По умолчанию без этого атрибута все открытые члены (свойства и поля) сериализуются.Сериализация следующего класса

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

    public string Password { get; set; }
}

дает следующий результат

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

Но когда класс помечен атрибутом [Serializable] и значение IgnoreSerializableAttribute равно false, все частные и открытыеполя сериализуются, и в результате получается следующее

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

По умолчанию сериализатор игнорирует атрибут [Serializable], но в Web API IgnoreSerializableAttribute имеет значение false.Теперь легко понять, почему сервер не может правильно десериализовать данную модель в вашем случае.

...