防止创建ActionResult的序列化

时间:2018-04-11 08:22:04

标签: c# json serialization asp.net-web-api2

假设我有一个异步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属性仍然是序列化的。

1 个答案:

答案 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应该比设置ShouldSerializeShouldDeserialize代表更简单,更高效。

  • 使用nameof可以避免对属性名称进行硬编码。

  • 如果稍后将名为Item的属性添加到某个不相关的类型,检查被序列化的类型是否继承ItemDescriptions似乎是明智的。

  • 您可以随时使用[JsonIgnore]标记该属性 - 除非该类型位于某个外部库中且无法修改。

示例工作.Net fiddle