问题
I have a complex object that is correctly deserialized from json in the browser, but when I post the same data back with jQuery, the child objects of an array aren't getting deserialized - they are all set to default values.
I've tried changing the collections types from List, to IEnumerables, but that has changed nothing. It is interesting that the number of elements I get back is the correct amount.
Also this is a CORS POST, but I haven't had any problems otherwise.
Models
public class Document
{
public int DocumentId { get; set; }
public DocumentType DocumentType { get; set; }
public string Name { get; set; }
public string Path { get; set; }
public IEnumerable<DocumentField> Fields { get; set; }
}
public class DocumentField
{
public int FieldId { get; set; }
public string Path { get; set; }
public IEnumerable<FieldRelationship> RelatedFields { get; set; }
}
public class FieldRelationship
{
public int RelationshipId { get; set; }
public int FieldId { get; set; }
}
Here is my controller method signature (notice I don't have [FromBody]
attribute on the parameter, when I did I got a null result).
[HttpPost]
public void Post(Web.Document webDoc)
jQuery
var res = $.get('http://localhost:11786/api/documents/1');
res.then(function (data) {
$.ajax({
type: 'POST',
url: 'http://localhost:11786/api/documents/',
crossDomain: true,
data: data,
success: function (responseData, textStatus, jqXHR) {
console.log('yes');
},
error: function (responseData, textStatus, errorThrown) {
console.log('failed');
}
});
});
What the Response Body looks like:
Fields[0][FieldId]=1410
&Fields[0][Path]=TestField
&Fields[0][RelatedFields][0][RelationshipId]=1
&Fields[0][RelatedFields][0][FieldId]=503
&Fields[0][RelatedFields][1][FieldId]=501
&Fields[1][Path]=cookies
&DocumentId=1
&DocumentType=2
&Name=Test Document
&Path=test.docx
What the values are in the resulting C# Documents instance
DocumentId: 1
DocumentType: 2
Name: "Test Document"
Path: "test.docx"
Fields: [{
FieldId: 0, <--- Bad
Path: null, <--- Bad
RelatedFields: null, <--- Bad
}, {
FieldId: 0, <--- Bad
Path: null, <--- Bad
RelatedFields: null
}]
Edit
Here are the results if I change how I send the data in the ajax call. Remember data is the variable that holds the result from get.
ajax.data [FromBody] Result
--------- ---------- ------
data false Props set, array count correct, array object props null
JSON.stringfy(data) false Object not null, but props null
{ "": data } false Object not null, but props null
"=" + JSON.stringfy false Object not null, but props null
data true null
JSON.stringfy(data) true null
{ "": data } true null
"=" + JSON.stringfy true null
If I use angular's $http.post ($http.post('http://localhost:11786/api/documents/', res.data);
) and add the [FromBody]
attribute to the method parameter, I get the correct results. It seems like somehow what I'm passing to data in $.ajax is not the right thing, even though I tried the four methods above.
回答1:
Add contentType
to your ajax setting object, JSON.stringify your doc object, post json string to server:
var doc = { DocumentId: 1 };
var jsonDoc = JSON.stringify(doc);
jQuery.ajax('api/test', {
type: 'POST',
data: jsonDoc,
contentType: 'application/json'
})
.done(function(data, status, jqr) {
alert(status);
})
It should works.
回答2:
Looks like you are hitting a known issue where binding to JQuery formurlencoded array format is not supported by model binding. Following issue is tracking it.
https://github.com/aspnet/Mvc/issues/211
Curious, is it on purpose that you are not setting the [FromBody]
..my question is as to why not send the data as json format when you are using ajax calls...Is it to avoid CORS pre-flight request?
来源:https://stackoverflow.com/questions/28465156/web-api-not-deserializing-properties-of-child-array-in-post