有时我需要通过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
,但我无法找到办法。
我尝试使用TypeNameHandling.None设置JsonSerializerSettings作为jsonconvert的输入,当我不想使用下面的代码"$type"
属性时:
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是:
{ “扩展”:[{ “的立即”:3 “URL”: “ewwer”}]}
但它包含"$type"
属性,如下所示:
{ “扩展”:[{ “$类型”:“DicomtoJsonConverter.IntegerExtension, DicomtoJsonConverter”, “的立即”:3 “URL”: “ewwer”}]}
如何在不更改"$type"
类的情况下抑制DomainResource
属性的输出?
答案 0 :(得分:1)
即使由custom ContractResolver
,JsonPropertyAttribute.TypeNameHandling
或JsonPropertyAttribute.ItemTypeNameHandling
指定,您也可以使用JsonContainerAttribute.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);
}
}
如果您使用的版本早于9.0.1的Json.NET,则需要继承CamelCasePropertyNamesContractResolver
而不是继承DefaultContractResolver
,因为该版本中引入了NamingStrategy
。