XmlSerializer,“指定”后缀和IReflect

问题描述 投票:6回答:3

我发现如果可序列化的Field / Property有一个Boolean类型的相应字段,其字段名称为“Specified”后缀,则XmlSerializer有条件地从序列化过程中排除该Field / Property。太好了!

所以,我想避免这些字段的定义,并在运行时动态添加它们......

阅读this,我找到了一个有趣的接口IReflect,我可以用它来“模拟”XmlSerializer实例用来排除某些字段的动态字段。

这会有用吗?

c# reflection xml-serialization
3个回答
2
投票

如果您想控制xml序列化,那么您有两个选择。第一个(这可能不适合)它使用System.Xml.Serialization命名空间中的属性来排除属性。如果您确实需要确定在运行时序列化的内容,那么这可能不是最好的操作方法。

Attributes That Control XML Serialization

另一种方法是在类上实现IXmlSerializable接口并实现ReadXml和WriteXml方法。这使您可以控制xml的外观。有关其他信息,请参阅此问题:

custom xml serialization

但是,正如这里提到的,Mixing custom and basic serialization?一旦实现IXmlSerializable,您就负责所有类型的序列化逻辑。


3
投票

我将扩展Martin Peck的答案。您可以避免使用“Specified”后缀序列化字段/属性。您应该在类中定义“* Specified”属性并将[XmlIgnoreAttribute()]应用于它们。

这是一个例子:

[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://yournamespace.com")]
public partial class YourObject
{
    private long sessionTimeoutInSecondsField;

    private bool sessionTimeoutInSecondsFieldSpecified;

    public long sessionTimeoutInSeconds
    {
        get
        {
            return this.sessionTimeoutInSecondsField;
        }
        set
        {
            this.sessionTimeoutInSecondsField = value;
        }
    }

    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool sessionTimeoutInSecondsSpecified
    {
        get
        {
            return this.sessionTimeoutInSecondsFieldSpecified;
        }
        set
        {
            this.sessionTimeoutInSecondsFieldSpecified = value;
        }
    }
}

0
投票

代码示例作为所提供答案的扩展;

WSDL:

<xs:simpleType name="vehicleType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="CAR" />
      <xs:enumeration value="BUS" />
      <xs:enumeration value="BIKE" />
    </xs:restriction>
  </xs:simpleType>
<xs:complexType name="advancedSearchRequest">
    <xs:sequence>
      <xs:element minOccurs="0" name="vehicleType" type="tns:vehicleType" />
      <xs:element name="search" type="xs:string" />
    </xs:sequence>
  </xs:complexType>

生成的.net SOAP客户端类

System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.3056.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="your namespace")]
public partial class advancedSearchRequest : object, System.ComponentModel.INotifyPropertyChanged {

    private vehicleType vehicleTypeField;

    private bool vehicleTypeFieldSpecified;

    private string searchField;


    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
    public vehicleType vehicleType {
        get {
            return this.vehicleTypeField;
        }
        set {
            this.vehicleTypeField = value;
            this.RaisePropertyChanged("vehicleType");
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool vehicleTypeSpecified {
        get {
            return this.vehicleTypeFieldSpecified;
        }
        set {
            this.vehicleTypeFieldSpecified = value;
            this.RaisePropertyChanged("vehicleTypeSpecified");
        }
    }

    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=3)]
    public string search {
        get {
            return this.searchField;
        }
        set {
            this.searchField = value;
            this.RaisePropertyChanged("search");
        }
    }

}

您可以将“vehicleTypeFieldSpecified”= {true / false}设置为{serialize / omit};

advancedSearchRequest.vehicleTypeField = vehicleType.BIKE;
advancedSearchRequest.vehicleTypeFieldSpecified = true;

产生的SOAP消息;

<advancedSearchRequests>
 <vehicleType>BIKE</vehicleType>
 <search>abc</search>
</advancedSearchRequest>
© www.soinside.com 2019 - 2024. All rights reserved.