【问题标题】:Web.Api not deserializing properties of Child Array in PostWeb.Api 没有反序列化 Post 中子数组的属性
【发布时间】:2015-04-12 11:05:03
【问题描述】:

我有一个复杂的对象,它在浏览器中从 json 正确反序列化,但是当我使用 jQuery 将相同的数据发回时,数组的子对象没有被反序列化 - 它们都设置为默认值。

我尝试将集合类型从 List 更改为 IEnumerables,但这并没有改变。有趣的是,我返回的元素数量是正确的。

这也是一个 CORS POST,但其他方面我没有遇到任何问题。

型号

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

这是我的控制器方法签名(请注意,我在参数上没有 [FromBody] 属性,当我得到一个空结果时)。

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

响应正文是什么样的:

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 

生成的 C# 文档实例中的值是什么

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
}]

编辑

如果我更改在 ajax 调用中发送数据的方式,以下是结果。记住 data 是保存 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

如果我使用 Angular 的 $http.post ($http.post('http://localhost:11786/api/documents/', res.data);) 并将 [FromBody] 属性添加到方法参数,我会得到正确的结果。即使我尝试了上面的四种方法,我在 $.ajax 中传递给数据的东西似乎也不是正确的。

【问题讨论】:

    标签: asp.net asp.net-web-api http-post asp.net-core


    【解决方案1】:

    contentType添加到您的ajax设置对象,JSON.stringify您的文档对象,将json字符串发布到服务器:

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

    它应该可以工作。

    【讨论】:

    • 添加 contentType: 'application/json' 用 [FromBody] 属性为我解决了问题。
    • @daniel-gimenez,Document 是一个复杂类型,web api 会从请求体中提取复杂参数,[FromBody] 属性不是必须的,我们只需要 post json 到控制器。跨度>
    【解决方案2】:

    看起来您遇到了一个已知问题,即模型绑定不支持绑定到 JQuery formurlencoded 数组格式。以下问题正在跟踪它。

    https://github.com/aspnet/Mvc/issues/211

    很好奇,您是否故意不设置[FromBody]..我的问题是为什么在使用 ajax 调用时不将数据发送为 json 格式...是为了避免 CORS 飞行前请求?

    【讨论】:

    • 我尝试发送 JSON,但结果总是为空。
    • 我理解他们mvc asp.net5合并了MVC和API,你只需要添加[FromBody]来处理两者。
    • @Stef 无论我如何尝试使用 [FromBody] 我都会得到空值。我尝试以各种方式传递数据,作为对象,作为 JSON.stringified 字符串,作为对象作为参数 {"":data} 和作为字符串参数 {"":str}。纳达。
    • @KiranChalla +1,因为您对问题的根源是正确的。你知道如何解决它吗?
    猜你喜欢
    • 2017-09-15
    • 1970-01-01
    • 2021-11-12
    • 2015-03-17
    • 2017-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-26
    相关资源
    最近更新 更多