1

im使用MVC 4我的ActionController收到
以下JSON:JSON反序列化在MVC 4控制器多态性阵列

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

所以,现在,我怎么可以管理MainClass反序列化时的动作控制器RECE我的JSON?因为当我调用行动的列表项是空的。

如果解决方案的一部分是Json.NET,怎么可以实现用于MVC 4个控制器?

感谢您的帮助。

回答

2

你需要一个属性或设置,您可以从中确定哪种类型的类就是用这种方法的属性。使用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; 
} 

有额外的一点点这里的开销,因为你要反序列化的两倍,但它是值得的在大多数情况下我,因为这很容易理解这是怎么回事,并根据需要增加新的类型。

+0

非常感谢保罗,我不能投你的答案,因为我的名气,但我想用模型绑定,因为我只使用网络api的CRUD操作。在模型绑定器的实现中,我找不到获取数组值的方法。例如: values [“MainId”] - >这是好的 values [“Actions”] - >这是空的,而不是它我发现值[“Actions [0] .Attribute1ClassA”] Is there没有办法让类似:值[“行动”]这样我就可以通过遍历数组做反序列化? – Luiggi

+0

是的,只要反序列化整个请求主体,然后动态地访问它以同样的方式:'result.Actions'。为了保持简单,您可以重新操作actions数组的每个实例,然后反序列化为正确的类型。 – Paul

0

您可以解析JSON成动态对象,而不是使用Json.NET

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;