为什么这个嵌套模型不像我期望的那样被反序列化?

时间:2013-07-30 17:09:42

标签: c# asp.net-mvc-4 json.net deserialization

请稍等一下,请忽略这个复杂模型的讽刺,并假设你坚持下去:)

public class Foo
{
   public FooList Foos{get;set;}
}

public class FooList
{
    public object SomeBar {get; set;}
}

public class Bar
{
    public string Name {get;set;}
}

public class AnotherBar
{
    public bool IsCrazy{get;set;}
}

因此,我们会将操作设为Foo,而foo将设置FooList,其中包含BarAnotherBar。 SomeBar包含的内容并不重要..它是一些KNOWN类型的对象,但我们不知道哪一个......哦,它们不会从共同的祖先继承。

好的,所以当你将json发布到一个采用Foo的动作时。 Foo对象将被反序列化,但FooList为null。如果我创建一个自定义的ModelBinder,请手动读取流并告诉JsonConvert对其进行反序列化。 一切正常

据我所知,MVC4使用了JsonConvert。这有什么区别?为什么内置的反序列化不起作用而我明确使用JsonConvert呢?

我可能要得到这笔钱,我打算尽可能多地投入(500?)

PS。我不是要求解决问题。我真的只是想知道导致这种行为的原因。

现在代码:

//some sample JSON: {"Foos":{"SomeBar":{"Name":"Insanity"}}}


public ActionResult Test(Foo foo)
{
     //Foo.FooList is null
    return new EmptyResult();
}

public ActionResult BinderTest([ModelBinder(typeof(FooModelBinder))] Foo foo)
{ 
    //Everything is as it should be
    return new EmptyResult();
}

public class FooModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var request = controllerContext.HttpContext.Request;
        request.InputStream.Seek(0, SeekOrigin.Begin);

        var jsonString = new StreamReader(request.InputStream).ReadToEnd();

        Foo foo = JsonConvert.DeserializeObject<Foo>(jsonString);

        return foo;
    }
}

一些客户端代码

$(function () {
        $('#button1').click(function () {
            var data = '{"Foos":{"SomeBar":{"Name":"Insanity"}}}';
            $.post('/home/bindertest', data);
        });

        $('#button2').click(function () {
            var data = '{"Foos":{"SomeBar":{"Name":"Insanity"}}}';
            $.post('/home/test', data);
        });
    });

1 个答案:

答案 0 :(得分:2)

MVC 4中 Web API 控制器(继承自ApiController的类)的默认序列化程序是Json.Net。但是,我认为标准 MVC 4控制器(继承自Controller的类)的默认序列化程序仍然是JavaScriptSerializer(出于向后兼容性原因)。见this question。所以这可以很好地解释行为上的差异。