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

本文关键字:模型 反序列化 动态 属性 定义 | 更新日期: 2023-09-27 17:57:11

我有一个定义如下的 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 正确进入我的模型。属性。但是,额外的属性是{对象},由于我不知道里面有什么,所以我无法以任何方式反序列化它。

我尝试让它动态和/或将其转换为动态/扩展对象/字典,但没有成功。我知道如果我只收到一个原始的 HttpRequestMessage 并自己处理它,我可能会让它工作。我宁愿不这样做,而是依靠 .NET 的所有验证。

可能吗?

谢谢

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

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

将属性定义为object应该有效,或者如果您想明确,您可以为您的Extra属性提供类型 JObject

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

  • 将内容类型设置为"应用程序/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'
            }
        }
    })
});