为什么不是';没有像我所期望的那样对这个嵌套模型进行反序列化

本文关键字:嵌套 反序列化 模型 期望 为什么不 | 更新日期: 2023-09-27 18:25:42

请暂时忽略这个复杂模型的滑稽之处,并假设你已经被它卡住了:)

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;}
}

因此,我们将给Action一个Foo,而foo将有一个FooList,它包含BarAnotherBar。SomeBar包含的内容其实并不重要。。它是一些已知类型的对象,但我们不知道是哪一个。。。哦,他们不是从共同的祖先那里继承的。

好吧,当你把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);
        });
    });

为什么不是';没有像我所期望的那样对这个嵌套模型进行反序列化

MVC 4中Web API控制器(继承自ApiController的类)的默认串行器是Json.Net。然而,我认为标准MVC 4控制器(继承自Controller的类)默认串行器仍然是JavaScriptSerializer(出于向后兼容性原因)。请参阅此问题。因此,这可以很好地解释行为上的差异。