如何在定义良好的模型中反序列化动态属性?

时间:2013-02-03 20:28:42

标签: c# json asp.net-web-api json.net deserialization

我的web api方法定义如下:

[HttpPost]
public void Post(Input model)
{
    ...
}  

使用这样的输入模型:

public class Input
{
    public string Id { get; set; }
    public object Extra { get; set; }
}

我想要做的是传递一个有效的JSON对象作为额外的参数,如下面的例子与jQuery:

$.post(
    'http://localhost/api/myController',
    { 
        id: 'someId',               
        extra: { 
            tags: ['a', 'b'],
            anotherValue: 'hello',
            oneMore: { 
                foo: 'bar'
            }
        }
    });

Id 正确进入我的model.Id属性。但是, extra 属性是{object},因为我不知道那里有什么我不能以任何方式反序列化它。

我尝试将其动态和/或将其投射到dynamic / ExpandoObject / Dictionary但没有成功。我知道如果我只是收到一个原始的HttpRequestMessage并自己处理它,我可能会使它工作。不过,我宁愿不这样做,并依赖于.NET所具有的所有验证。

有可能吗?

由于

编辑1:在测试了更多替代方案后,我发现 extra 属性没有任何实际值,它只是初始化为新对象() 。看起来默认的模型绑定器实现不处理动态JSON(至少不是这样)并且只是调用它无法处理的模型属性的默认构造函数。

1 个答案:

答案 0 :(得分:0)

将您的媒体资源定义为object应该有效,或者如果您想要明确,则可以为Extra媒体资源JObject添加。

然而问题出在$.post请求上。为了将复杂数据发布到web.api方法并允许模型绑定,您需要做两件事:

  • 将内容类型设置为“application / json”
  • 并将数据作为JSON发送,并在其上调用JSON.stringify

但是使用$.post您无法指定内容类型,因此您需要使用$.ajax

因此,以下调用应将数据发布到您的操作:

$.ajax({
    url: 'http://localhost/api/myController',
    type: 'POST',
    contentType: 'application/json',
    data: JSON.stringify(
    { 
        id: 'someId',               
        extra: { 
            tags: ['a', 'b'],
            anotherValue: 'hello',
            oneMore: { 
                foo: 'bar'
            }
        }
    })
});