我正在实现一个使用JSON.NET进行序列化的Web API 2服务。
当我尝试PUT(deselalize)更新的json数据时,抽象类不存在,这意味着它不知道该怎么处理它,所以什么也没做。我还尝试使类不抽象,只是从中继承,然后每个PUT都被取消到基类,而不是缺少派生类属性的派生类。
示例:
public class People
{
// other attributes removed for demonstration simplicity
public List<Person> 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被配置为进行类型名称处理:
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);
}
但检查CCD_ 1时的输出总是:
People == { People: [] }
或者如果不是抽象的:
People == { People: [{ Name: "Larry", Id: "123" }] }
丢失了固有的财产。有人遇到这个问题并想出什么办法吗?
$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"
}]
}
序列化程序能够将对象取消关联为正确的强制转换。我太喜欢了!
我现在已经尝试过您的场景,它运行良好。但我注意到您在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<Person> 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;}
}
- 选择一个字段并为每个子类指定其值,或者
- 指定仅存在于特定子类中的字段
我遇到了一个非常类似的问题。对我有用的是添加一个默认构造函数来初始化类中的对象。请确保初始化每个对象。在您的情况下,您需要将构造函数添加到People类中。
public class People
{
public People()
{
People = new List<Person>();
}
public List<Person> People { get;set; }
}
此外,这似乎是一个要么全有要么全无的镜头。如果不初始化任何包含的对象,则它们都不会包含值。