Mic*_*dej 13 c# serialization json.net
各位程序员,我在Newtonsoft.Json中遇到过一个奇怪的行为.
当我试图序列化一个看起来像这样的对象:
public class DMSDocWorkflowI
{
[JsonProperty("DMSDocWorkflowIResult")]
public bool DMSDocWorkflowIResult { get; set; }
[JsonProperty("DMSDocWorkflowIResultSpecified")]
public bool DMSDocWorkflowIResultSpecified { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
使用这个简单的调用,没有自定义转换器/绑定器/合同解析器:
var testObject = new DMSDocWorkflowI();
var json = JsonConvert.SerializeObject(testObject, Formatting.Indented);
Run Code Online (Sandbox Code Playgroud)
或者甚至JToken.FromObject(...)我总是只得到一处房产:
{
"DMSDocWorkflowIResultSpecified": false
}
Run Code Online (Sandbox Code Playgroud)
当我附加跟踪编写器时,它只捕获这个:
[0]: "2016-08-30T11:06:27.779 Info Started serializing *****DMSDocWorkflowI. Path ''."
[1]: "2016-08-30T11:06:27.779 Verbose IsSpecified result for property 'DMSDocWorkflowIResult' on *****DMSDocWorkflowI: False. Path ''."
[2]: "2016-08-30T11:06:27.779 Info Finished serializing *****.DMSDocWorkflowI. Path ''."
[3]: "2016-08-30T11:06:27.780 Verbose Serialized JSON: \r\n{\r\n \"DMSDocWorkflowIResultSpecified\": false\r\n}"
Run Code Online (Sandbox Code Playgroud)
所以似乎Newtonsoft.Json有些神奇地对待这个"Specified"属性.我能把它关掉吗?我在生成的JSON中需要这些属性以及这些名称.
dbc*_*dbc 11
在Json.NET 4.0.1发行说明中非常简要地提到了这种行为:新功能 - 添加了XmlSerializer样式指定的属性支持.该功能又在MinOccurs属性绑定支持中描述:XmlSerializer
[对于可选字段] Xsd.exe生成一个类型
bool的公共字段,其名称是元素字段的名称,附加了Specified.例如,如果元素字段的名称是startDate,则bool字段的名称将变为startDateSpecified.将对象序列化为XML时,XmlSerializer类会检查bool字段的值以确定是否编写该元素.
我觉得这个功能应该记录在这里,但事实并非如此.您可能想要打开 Newtonsoft 的文档问题.
由于您不希望出现此行为,因此如果您使用的是Json.NET 11.0.1或更高版本,则可以通过实例化您自己的DefaultContractResolver设置并进行设置来禁用所有类DefaultContractResolver.IgnoreIsSpecifiedMembers = true:
public static class JsonContractResolvers
{
// As of 7.0.1, Json.NET suggests using a static instance for "stateless" contract resolvers, for performance reasons.
// http://www.newtonsoft.com/json/help/html/ContractResolver.htm
// http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Serialization_DefaultContractResolver__ctor_1.htm
// "Use the parameterless constructor and cache instances of the contract resolver within your application for optimal performance."
public static readonly DefaultContractResolver IgnoreIsSpecifiedMembersResolver =
new DefaultContractResolver { IgnoreIsSpecifiedMembers = true };
}
Run Code Online (Sandbox Code Playgroud)
然后将其传递给JsonConvert如下:
var settings = new JsonSerializerSettings { ContractResolver = JsonContractResolvers.IgnoreIsSpecifiedMembersResolver };
var json = JsonConvert.SerializeObject(testObject, Formatting.Indented, settings);
Run Code Online (Sandbox Code Playgroud)
或者创建一个JTokendo:
var jToken = JToken.FromObject(testObject, JsonSerializer.CreateDefault(settings));
Run Code Online (Sandbox Code Playgroud)
如果您使用的是早期版本,则需要创建并缓存自定义合约解析程序:
public static class JsonContractResolvers
{
// As of 7.0.1, Json.NET suggests using a static instance for "stateless" contract resolvers, for performance reasons.
// http://www.newtonsoft.com/json/help/html/ContractResolver.htm
// http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Serialization_DefaultContractResolver__ctor_1.htm
// "Use the parameterless constructor and cache instances of the contract resolver within your application for optimal performance."
public static readonly DefaultContractResolver IgnoreIsSpecifiedMembersResolver =
new IgnoreSpecifiedContractResolver();
}
internal class IgnoreSpecifiedContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
property.GetIsSpecified = null;
property.SetIsSpecified = null;
return property;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2563 次 |
| 最近记录: |