简体   繁体   English

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

[英]How to deserialize a dynamic property in a well defined model?

I have a web api method defined as follows: 我有一个Web api方法定义如下:

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

With Input model like this: 使用这样的输入模型:

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

What I want to do is pass a valid JSON object as the extra parameter like the following example with jQuery: 我想做的就是传递一个有效的JSON对象作为额外的参数,例如下面的jQuery示例:

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

Id comes correctly into my model.Id property. ID正确进入了我的model.Id属性。 However, the extra property comes as an {object} and since I don't know whats in there I cannot deserialize it in any way. 但是, 额外的属性作为{object}出现,由于我不知道其中的内容,因此无法以任何方式反序列化它。

I tried making it dynamic and/or casting it to dynamic/ExpandoObject/Dictionary without success. 我尝试使其动态化和/或将其强制转换为dynamic / ExpandoObject / Dictionary,但未成功。 I know that I can probably make it work if I just receive a raw HttpRequestMessage and handle it myself. 我知道,如果我只收到原始的HttpRequestMessage并自己处理,就可以使它工作。 Hoever I would rather not do it and rely in all validations that .NET has in place. 但是,我宁愿不这样做,而要依靠.NET进行的所有验证。

Is it possible? 可能吗?

Thanks 谢谢

EDIT 1: After testing some more alternatives I found that the extra property does not have any real value and it's just initialized as a new object() . 编辑1:在测试了更多替代方案之后,我发现extra属性没有任何实际值,它只是被初始化为new object() Looks like the default model binder implementation does not deal with dynamic JSON (at least not like this) and simply call the default constructor of the model property that it cannot deals with. 看起来默认的模型绑定程序实现不处理动态JSON(至少不是这样),而只是调用它无法处理的model属性的默认构造函数。

Defining your property as object should work or if you want to be explicit you give your Extra property the type JObject . 将属性定义为object应该可以,或者如果要明确显示, JObject Extra属性的类型设置为JObject

However the problem is with $.post request. 但是问题出在$.post请求上。 In order to post complex data to a web.api method and allow the model binding you need to do two things: 为了将复杂的数据发布到web.api方法并允许模型绑定,您需要做两件事:

  • set the content type to 'application/json' 将内容类型设置为“ application / json”
  • and send the data as JSON with calling JSON.stringify on it 并通过调用JSON.stringify将数据作为JSON发送

But with $.post you cannot specify the content type so you need to use $.ajax : 但是使用$.post不能指定内容类型,因此需要使用$.ajax

So the following call should post the data to your action: 因此,以下调用应将数据发布到您的操作中:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM