如何在序列化时为每个集合禁用TypeNameHandling?

时间:2016-05-10 12:29:37

标签: c# dynamic json.net

我正在尝试将一些弱类型的数据从ASP.NET MVC主机发送到JavaScript客户端。类型较弱意味着此处具有object类型属性,或者结果为ExpandoObject

由于TypeNameHandling = TypeNameHandling.Auto设置(我需要弱类型对象),我也会收集集合的$type注释,从而产生不同的JSON结构:而不是简单的数组,我将它包裹在{ $type: ..., $values: ... }结构中。

我怎样才能为每种集合全局省略?

我尝试实施自定义合约解析程序,但似乎不适用于ExpandoObject

public class JsonWebAPIContractResolver : DefaultContractResolver
{
    public bool SkipTypNameHandlingOnCollections { get; set; }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);
        if (SkipTypNameHandlingOnCollections && property.PropertyType.IsCollectionType())
            property.TypeNameHandling = TypeNameHandling.None;
        return property;
    }
}

在代码中我有一个很好的旧扩展方法Type.IsCollectionType,它可以正常工作。也许问题是动态对象没有“通过”合同解决机制?

1 个答案:

答案 0 :(得分:1)

事实证明,Json.NET为我的DictionaryContract创建了ExpandoObject,这就是为什么它没有通过CreateProperty。当然,这在第二眼看来是有道理的。

所以我设法通过上面提到的自定义合约解析器的以下扩展来实现我的目标。

protected override JsonDictionaryContract CreateDictionaryContract(Type objectType)
{
    var c = base.CreateDictionaryContract(objectType);
    if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom( c.UnderlyingType))
        c.ItemTypeNameHandling = TypeNameHandling.None;
    return c;
}

通过这个解决方案,我实现了一个不同的目标:我为任何动态对象类型的每个动态属性关闭了typename处理,但在这种情况下,这对我来说完全没问题。