Reputation: 623
client side code:
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();
}
Web API:
[HttpPost]
[Route("api/Login")]
public IHttpActionResult ValidateLogin([FromBody]UserModel user)
{
var result = _service.FetchUser(user);
return Json(result);
}
UserModel
[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; }
}
No data arrives in ValidateLogin, even when I pass parameters with the postman.
I have searched a lot, found no solution at all, tried all the code snippets, understood them then came back and so on, I'm stuck, what is wrong?
Upvotes: 2
Views: 3144
Reputation: 9642
Solution 1
Just remove [Serializable]
attribute from UserModel
and everything will work fine.
Solution 2
When serializing data on client use json serialization behavior as Web API
does
var serializedData = JsonConvert.SerializeObject(data, new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
IgnoreSerializableAttribute = false
}
});
Now Web API
will correctly deserialize passed model.
This happens because starting from some version Json.NET
considers if object is marked as Serializable
. By default without that attribute all public members (properties and fields) are serialized. Serialization of the following class
public class UserModel
{
public string Username { get; set; }
public string Password { get; set; }
}
gives the following result
{
"Username": "name",
"Password": "pass"
}
But when class is marked by [Serializable]
attribute and IgnoreSerializableAttribute
setting is false
all private and public fields are serialized and result is the following
{
"<Username>k__BackingField": "name",
"<Password>k__BackingField": "pass"
}
By default serializer ignores [Serializable]
attribute but in Web API
the IgnoreSerializableAttribute
is set to false
. So now it's easy to see why server couldn't properly deserialize given model in your case.
Upvotes: 8