在ASP.NET Web API中反序列化为派生类

时间:2012-11-09 14:56:54

标签: asp.net-web-api json.net

In my last SO question,我问过如何修改Json.NET的序列化程序设置,ASP.NET Web API本身用于(反)序列化。接受的答案非常有效,例如,我可以将类型信息嵌入到序列化的JSON字符串中。

但是,当我尝试将此JSON字符串返回到期望模型的父类的Web API操作时,Web API仍然反序列化为父类,删除与子类相对应的所有数据,并阻止转换和检测儿童班。

class Entity { }
class Person : Entity { }

public Person Get() {
    return new Person();
}

public bool Post(Entity entity) {
    return entity is Person;
}

一个简单的用例就是在jQuery中做这样的事情:

// get a serialized JSON Person
$.ajax({
    url : 'api/person'      // PersonController
}).success(function (m) {

    // then throw that Person right back via HTTP POST
    $.ajax({
        url : 'api/person',
        type : 'POST',
        data : m
    }).success(function (m) {
        console.log(m);     // false
    });

})

我希望通过修改Json.NET的JsonSerializerSettings来嵌入它能够读取的类型信息,并且至少尝试强制反序列化到该类型,但显然它没有。

我应该如何处理这样的事情?

2 个答案:

答案 0 :(得分:1)

Web API确实没有“本地”进行任何(反)序列化。它默认情况下在config.Formatters集合中包含一些MediaTypeFormatters。您可以随意删除它们并创建自己的MediaTypeFormatter,以按照您希望的方式处理序列化。

MediaTypeFormatters实际上并不难创建。

答案 1 :(得分:1)

实际上,第二个POST调用正在发送application / x-www-form-urlencoded数据,这就是JsonMediaTypeFormatter没有获取类型信息的原因。尝试将contentType设置为“application / json”。

此外,第二个POST请求正文中的数据似乎已被编码,需要在发送回服务之前对其进行解码。

我能够让这个工作:

    // get a serialized JSON Person
    $.ajax({
        url: 'api/person'      // PersonController
    }).success(function (m) {

        // then throw that Person right back via HTTP POST
        $.ajax({
            url: 'api/person',
            type: 'POST',
            contentType: "application/json",
            data: JSON.stringify(m),
        }).success(function (m) {
            alert(m);     // true!
        });

    })