XSD.EXE + JSON.NET – 如何处理xxxSpecified生成的成员?

当使用XSD.EXE从XML Schema生成类时,它会生成给定对象的任何基元的xxxSpecified成员:

     

….产生:

 public class Foo { public int Count { get; set; } public bool CountSpecified { get; set; } } 

看来最新版本的JSON.NET可以在反序列化时自动设置这些属性。

 string request = "{ Count : 10 }"; var object = JsonConvert.Deserialize(request) Assert.IsTrue(object.Count = 10); // Yup Assert.IsTrue(object.CountSpecified == true); //Also yup - JSON.NET works! 

但是,当采用另一种方式时,xxxSpecified属性包含在JSON输出中,这是不正确的,因为它不是模式的一部分。

 string request = JsonConvert.Serialize(object); //{ // Count: 10, // CountSpecified : true <-- This is incorrect - should not be output //} 

是否有任何我缺少的设置控制是否输出xxxSpecified属性? 我怎么能抑制它?

(注意:这是这里回答的问题的排列:

JSON.NET,XmlSerializer和“Specified”属性

…但它涉及创建扩展类,这对我来说是不可能的,因为模式中有数百个类,我无法更改inheritance层次结构。 所以答案是行不通的。 寻找另一种方式。)

您可以创建自己的合约解析程序以过滤掉xxxSpecified属性:

 public class SkipSpecifiedContractResolver : DefaultContractResolver { // 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." static SkipSpecifiedContractResolver instance; static SkipSpecifiedContractResolver() { instance = new SkipSpecifiedContractResolver(); } public static SkipSpecifiedContractResolver Instance { get { return instance; } } protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) { var properties = base.CreateProperties(type, memberSerialization); ILookup lookup = null; foreach (var property in properties) { if (property.GetIsSpecified != null && property.SetIsSpecified != null) { var name = property.UnderlyingName + "Specified"; lookup = lookup ?? properties.ToLookup(p => p.UnderlyingName); var specified = lookup[name].SingleOrDefault(); if (specified != null) specified.Ignored = true; } } return properties; } } 

然后使用它像:

  var settings = new JsonSerializerSettings { ContractResolver = SkipSpecifiedContractResolver.Instance }; var object = JsonConvert.DeserializeObject(request, settings); 

如果要始终执行此操作,可以在全局JsonConvert.DefaultSettings设置合同解析程序:

  JsonConvert.DefaultSettings = (() => { return new JsonSerializerSettings { ContractResolver = SkipSpecifiedContractResolver.Instance }; });