gpt4 book ai didi

c# - 如何在 Json.NET 中使用 JsonSerializerSettings 在属性中指定时禁用 TypeNameHandling?

转载 作者:太空宇宙 更新时间:2023-11-03 12:21:41 25 4
gpt4 key购买 nike

有时我需要通过 Json.NET 抑制 "$type" 属性的输出,即使由 JsonPropertyAttribute.ItemTypeNameHandling 指定也是如此.如何做到这一点?

我的根类如下所示:

public class DomainResource
{
[JsonProperty(ItemTypeNameHandling = TypeNameHandling.Auto)]
public List<Extension> Extensions { get; set; }
}

此外,我还有一个用于Extension 的类层次结构,如下所示:

public class Extension
{
readonly string url;

public string Url { get { return url; } }

public Extension(string url)
{
this.url = url;
}
}

public class IntegerExtension : Extension
{
public IntegerExtension(string url) : base(url) { }

[JsonProperty("ValueInteger")]
public int Value { get; set; }
}

我想在序列化过程中的某些情况下忽略 ItemTypeNameHandling,但我无法找到一种方法来做到这一点。当我不想使用以下代码的 "$type" 属性时,我尝试使用 TypeNameHandling.None 设置 JsonSerializerSettings 作为 jsonconvert 的输入:

public static string SerializeObject(object value)
{
JsonSerializerSettings jsonSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore,
TypeNameHandling = TypeNameHandling.None,

};
jsonSettings.Converters.Add(new StringEnumConverter
{
CamelCaseText = true
});
return JsonConvert.SerializeObject(value, Formatting.None, jsonSettings);
}

然后按如下方式使用它:

var res = new DomainResource();
res.Extensions = new List<Extension>();
res.Extensions.Add(new IntegerExtension("ewwer"){Value = 3});

var x = CustomJsonConvert.SerializeObject(res);

我想要的 JSON 是:

{"extensions":[{"valueInteger":3,"url":"ewwer"}]}

但它包含 "$type" 属性,如下所示:

{"extensions":[{"$type":"DicomtoJsonConverter.IntegerExtension, DicomtoJsonConverter","valueInteger":3,"url":"ewwer"}]}

如何在不更改 DomainResource 类的情况下抑制 "$type" 属性的输出?

最佳答案

您可以使用 custom ContractResolver即使由 JsonPropertyAttribute.TypeNameHandling 指定,也可以抑制类型信息的输出, JsonPropertyAttribute.ItemTypeNameHandlingJsonContainerAttribute.ItemTypeNameHandling .首先,定义以下契约解析器:

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;
}
}

然后,修改CustomJsonConvert.SerializeObject()如下:

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);
}
}

如果您使用的 Json.NET 版本早于 9.0.1NamingStrategy 以来,您将需要子类化 CamelCasePropertyNamesContractResolver 而不是子类化 DefaultContractResolver在该版本中引入。

关于c# - 如何在 Json.NET 中使用 JsonSerializerSettings 在属性中指定时禁用 TypeNameHandling?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46925930/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com