【问题标题】:JSON Deserialization for polymorphic array in MVC 4 controllerMVC 4控制器中多态数组的JSON反序列化
【发布时间】:2012-12-14 20:22:40
【问题描述】:

我使用 MVC 4 我的 ActionController 接收到以下 Json:

{
    "MainId": 1,
    "Actions": [
        {
            "Attribute1ClassA": 1,
            "Attribute2ClassA": 2
        },
        {
            "Attribute1ClassB": 3,
            "Attribute2ClassB": 4
        },
        {
            "Attribute1ClassC": 5
        }
    ]
}

和控制器:

[HttpPost]
public ActionResult Commit(ActionsSummaryViewModel summary)
{
//DO stuff
}

类的声明:

public ActionsSummaryViewModel
{
    public int MainId {get;set;}
    public IList<MainClass> {get;set;}
}

public class MainClass
{
}

public class ClassA : MainClass
{
   public int Attribute1ClassA {get;set;}
   public string Attribute2ClassA {get;set;}
}

public class ClassB : MainClass
{
   public int Attribute1ClassB {get;set;}
   public string Attribute2ClassB {get;set;}
}

public class ClassC : MainClass
{
   public int Attribute1ClassC {get;set;}
}

那么现在,当动作控制器接收到 JSON 时,我该如何管理 MainClass 的反序列化?因为当我调用该操作时,列表项为空。

如果解决方案的一部分是 Json.NET,我该如何实现 MVC 4 控制器?

感谢您的帮助。

【问题讨论】:

    标签: asp.net-mvc serialization polymorphism json.net deserialization


    【解决方案1】:

    您需要一个属性或一组属性,您可以从中确定类要使用此方法的类型。使用 JSON.NET,我将传入的 JSON 反序列化为动态对象,然后检查公共属性,确定类型,并使用我的模型类型再次反序列化该类型的值:

    // I'm assuming here you've already got your raw JSON stored in 'value'
    // In my implementation I'm using the Web API so I use a media formatter,
    // but the same principle could be applied to a model binder or however 
    // else you want to read the value.
    
    dynamic result = JsonConvert.DeserializeObject(value);
    switch ((string)result.type)
    {
    case "typeone":
    return JsonConvert.DeserializeObject<ModelOne>(value);
    // ...
    default: return null;
    }
    

    这里有一点额外的开销,因为您要反序列化两次,但在大多数情况下对我来说这是值得的,因为它很容易理解发生了什么并根据需要添加新类型。

    【讨论】:

    • 非常感谢 Paul,由于我的声誉,我无法为您的答案投票,但是,我尝试使用模型绑定器,因为我只使用 web api 进行 CRUD 操作。在模型绑定器的实现中,我找不到获取数组值的方法。比如: values["MainId"] --> 这是好的 values["Actions"] --> 这是空的,而不是它我发现 values["Actions[0].Attribute1ClassA"] 有什么方法可以得到一些东西比如:values["Actions"] 这样我就可以遍历数组并进行反序列化?
    • 是的,只需反序列化整个请求正文,然后以相同的方式动态访问它:result.Actions。为了简单起见,您可以重新序列化操作数组的每个实例,然后反序列化为正确的类型。
    【解决方案2】:

    您可以使用 Json.NET 将 JSON 解析为动态对象:

    using Newtonsoft.Json.Linq:
    
    dynamic data = JObject.Parse("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");
    
    string name = data.Name;
    string address = data.Address.City;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-26
      • 1970-01-01
      • 2012-12-28
      • 1970-01-01
      • 2013-07-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多