假设我有一个异步web api 2控制器方法,返回一个Created ActionResult,如:
return Created(new Uri(Request.RequestUri + "/" + Item.Id), Item);
Item
有一个属性ItemDescriptions
,我希望在回复时将其截断。如何为这样的Created Web Api响应定义序列化?
我尝试创建一个自定义解析器,如:
public class ItemContractResolver: CamelCasePropertyNamesContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (property.PropertyName == "ItemDescriptions")
{
property.ShouldSerialize = i => false;
property.ShouldDeserialize = i => false;
}
return property;
}
}
我后来在Controller构造函数中设置了:
var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.ContractResolver = new ItemContractResolver();
但遗憾的是,ItemDescriptions
属性仍然是序列化的。
答案 0 :(得分:1)
JsonProperty.PropertyName
是该媒体资源的序列化名称。由于您继承自CamelCasePropertyNamesContractResolver
,因此会"itemDescriptions"
。
相反,请检查JsonProperty.UnderlyingName
,它是基础成员或参数的名称:
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (typeof(Item).IsAssignableFrom(property.DeclaringType)
&& property.UnderlyingName == nameof(Item.ItemDescriptions))
{
property.Ignored = true;
}
return property;
}
备注 -
设置JsonProperty.Ignored
应该比设置ShouldSerialize
和ShouldDeserialize
代表更简单,更高效。
使用nameof
可以避免对属性名称进行硬编码。
如果稍后将名为Item
的属性添加到某个不相关的类型,检查被序列化的类型是否继承ItemDescriptions
似乎是明智的。
您可以随时使用[JsonIgnore]
标记该属性 - 除非该类型位于某个外部库中且无法修改。
示例工作.Net fiddle。