使用WebAPI进行JSON.NET抽象/派生类反序列化2

我正在实现一个使用JSON.NET进行序列化的Web API 2服务。

当我尝试PUT(deseralize)更新的json数据时,抽象类不存在意味着它不知道如何处理它所以它什么也没做。 我也尝试使类不是抽象的,只是从它inheritance,然后每个PUT去除了基类,而不是缺少了类的属性。

例:

public class People { // other attributes removed for demonstration simplicity public List People { get;set; } } public abstract class Person { public string Id {get;set;} public string Name {get;set;} } public class Employee : Person { public string Badge {get;set;} } public class Customer : Person { public string VendorCategory {get;set;} } 

我的web api配置为进行typename处理:

 public static void Register(HttpConfiguration config) { config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Objects; } 

然后我把JSON像:

 { people: [{ name: "Larry", id: "123", badge: "12345", $type: "API.Models.Employee, API" }] } 

到web api方法:

 public HttpResponseMessage Put(string id, [FromBody]People value) { people.Update(value); // MongoDB Repository method ( not important here ) return Request.CreateResponse(HttpStatusCode.OK); } 

但检查value时的输出始终为:

 People == { People: [] } 

或者如果不是抽象的:

 People == { People: [{ Name: "Larry", Id: "123" }] } 

缺少inheritance的属性。 任何人遇到这个问题并想出任何东西?

$type函数必须是对象中的第一个属性。

在上面的例子中我做了:

  { people: [{ name: "Larry", id: "123", badge: "12345", $type: "API.Models.Employee, API" }] } 

$type移到顶部之后:

  { people: [{ $type: "API.Models.Employee, API", name: "Larry", id: "123", badge: "12345" }] } 

序列化程序能够将对象deseralize到正确的强制转换。 一定要喜欢!

我现在已经尝试了你的方案,它运行正常。 但我确实注意到你在json输入中的id属性之后缺少一个(逗号)。

我通过在我的操作中使用以下ModelState有效性检查来解决这个问题,然后在我的请求有效负载中显示错误。 这对你也很有用:

 if (!ModelState.IsValid) { return Request.CreateErrorResponse(HttpStatusCode.BadRequest, this.ModelState); } 

我知道这篇文章现在已经过时了,答案已经标明,但我认为我的解决方案可能会有所帮助….

尝试将JsonProperty属性添加到抽象类的属性中。

  using JTC.Framework.Json; ... public class People { // other attributes removed for demonstration simplicity public List People { get;set; } } public abstract class Person { [JsonProperty()] public string Id {get;set;} [JsonProperty()] public string Name {get;set;} } public class Employee : Person { public string Badge {get;set;} } public class Customer : Person { public string VendorCategory {get;set;} } 

JsonSubTypes库允许指定给定类的哪个子类应该用于反序列化为via属性,就像Java中的Jackson库一样。 更具体地说,您可以:

  • 选择一个字段并为每个子类指定其值,或
  • 指定仅存在于某个子类中的字段。

我有一个非常相似的问题。 对我有用的是添加一个初始化类中对象的默认构造函数。 确保初始化每个对象。 在您的情况下,您需要将构造函数添加到People类。

 public class People { public People() { People = new List(); } public List People { get;set; } } 

此外,这似乎是一个全有或全无的镜头。 如果不初始化任何包含的对象,则它们都不包含值。