C# XSD.EXE+;JSON.NET-如何处理XXX指定的生成成员?

C# XSD.EXE+;JSON.NET-如何处理XXX指定的生成成员?,c#,json.net,xmlserializer,C#,Json.net,Xmlserializer,使用XSD.EXE从XML模式生成类时,它会生成给定对象的任何原语的xxx指定成员: <xs:complexType name ="Foo"> <xs:all> <xs:element name ="Count" type = "xs:integer"/> </xs:all> </xs:complexType> 最新版本的JSON.NET似乎可以在反序列化时自动设置这些属性 string request =

使用XSD.EXE从XML模式生成类时,它会生成给定对象的任何原语的xxx指定成员:

<xs:complexType name ="Foo">
    <xs:all>
      <xs:element name ="Count" type = "xs:integer"/>
    </xs:all>
</xs:complexType>
最新版本的JSON.NET似乎可以在反序列化时自动设置这些属性

string request = "{ Count : 10 }";
var object = JsonConvert.Deserialize<Foo>(request)
Assert.IsTrue(object.Count = 10); // Yup
Assert.IsTrue(object.CountSpecified == true);  //Also yup - JSON.NET works!
string请求=“{Count:10}”;
var object=JsonConvert.Deserialize(请求)
Assert.IsTrue(object.Count=10);//是的
Assert.IsTrue(object.CountSpecified==true)//是的,JSON.NET也可以工作!
但是,如果换一种方式,xxx指定的属性会包含在JSON输出中,这是不正确的,因为它不是模式的一部分

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

//CountSpecified:true您可以创建自己的合同解析程序,以筛选出指定的属性:

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<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var properties = base.CreateProperties(type, memberSerialization);
        ILookup<string, JsonProperty> 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]
                    // Possibly also check for [XmlIgnore] being applied.  While not shown in the question, xsd.exe will always
                    // apply [XmlIgnore] to xxxSpecified tracking properties.
                    //.Where(p => p.AttributeProvider.GetAttributes(typeof(System.Xml.Serialization.XmlIgnoreAttribute),true).Any())
                    .SingleOrDefault();
                if (specified != null)
                    specified.Ignored = true;
            }
        }
        return properties;
    }
}

回答得很好。工作很有魅力。谢谢!
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<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var properties = base.CreateProperties(type, memberSerialization);
        ILookup<string, JsonProperty> 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]
                    // Possibly also check for [XmlIgnore] being applied.  While not shown in the question, xsd.exe will always
                    // apply [XmlIgnore] to xxxSpecified tracking properties.
                    //.Where(p => p.AttributeProvider.GetAttributes(typeof(System.Xml.Serialization.XmlIgnoreAttribute),true).Any())
                    .SingleOrDefault();
                if (specified != null)
                    specified.Ignored = true;
            }
        }
        return properties;
    }
}
var settings = new JsonSerializerSettings { ContractResolver = SkipSpecifiedContractResolver.Instance };
var object = JsonConvert.DeserializeObject<Foo>(request, settings);
JsonConvert.DefaultSettings = (() =>
{
    return new JsonSerializerSettings { ContractResolver = SkipSpecifiedContractResolver.Instance };
});