1

请暂时忽略这个复杂模型的讽刺,假设你被它困住了:)

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 aFoo并且 foo 将有一个FooListwhich contians 要么Bar要么AnotherBar。SomeBar 包含什么并不重要..它是几个已知类型的对象,但我们不知道是哪一个......哦,它们不是从共同的祖先继承的。

好的,所以当您将 json 发布到需要 Foo 的操作时。Foo 对象将被反序列化,但 FooList 为空。如果我创建一个自定义 ModelBinder,手动读取流并告诉 JsonConvert 反序列化它。一切正常

据我了解,MVC4 在幕后使用 JsonConvert。这里有什么区别?为什么内置反序列化不起作用而我明确使用 JsonConvert 会起作用?

我可能不得不赏金,我计划尽可能多地投入(500?)

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

现在看代码:

//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);
        });
    });
4

1 回答 1

2

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

于 2013-07-30T18:36:40.817 回答