How to disable TypeNameHandling when specified in attributes by using JsonSerializerSettings in Json.NET?

假如想象 提交于 2019-12-06 11:34:55

You can use a custom ContractResolver to suppress output of type information even when specified by JsonPropertyAttribute.TypeNameHandling, JsonPropertyAttribute.ItemTypeNameHandling or JsonContainerAttribute.ItemTypeNameHandling. First, define the following contract resolver:

public class NoTypeNameHandlingContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);
        // Suppress JsonPropertyAttribute.TypeNameHandling
        property.TypeNameHandling = null;
        // Suppress JsonPropertyAttribute.ItemTypeNameHandling
        property.ItemTypeNameHandling = null;
        return property;
    }

    protected override JsonContract CreateContract(Type objectType)
    {
        var contract = base.CreateContract(objectType);
        if (contract is JsonContainerContract)
        {
            // Suppress JsonContainerAttribute.ItemTypeNameHandling
            ((JsonContainerContract)contract).ItemTypeNameHandling = null;
        }
        return contract;
    }
}

Then, modify CustomJsonConvert.SerializeObject() as follows:

public static class CustomJsonConvert
{
    // You may want to cache the contract resolver for best performance, see
    // https://stackoverflow.com/questions/33557737/does-json-net-cache-types-serialization-information
    static readonly JsonSerializerSettings jsonSettings;
    static CustomJsonConvert()
    {
        jsonSettings = new JsonSerializerSettings
        {
            ContractResolver = new NoTypeNameHandlingContractResolver
            {
                NamingStrategy = new CamelCaseNamingStrategy
                {
                    // These are the settings used by CamelCasePropertyNamesContractResolver by default.
                    // Change them if this is not what you want.
                    OverrideSpecifiedNames = true,
                    ProcessDictionaryKeys = true,
                },
            },
            NullValueHandling = NullValueHandling.Ignore,
            TypeNameHandling = TypeNameHandling.None,
            Converters = { new StringEnumConverter { CamelCaseText = true } },
        };
    }

    public static string SerializeObject(object value)
    {
        return JsonConvert.SerializeObject(value, Formatting.None, jsonSettings);
    }
}

If you are using a version of Json.NET that predates 9.0.1 you will need to subclass CamelCasePropertyNamesContractResolver rather than subclassing DefaultContractResolver since NamingStrategy was introduced in that release.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!