XmlSerializer,“指定”后缀和IReflect

时间:2010-11-23 21:16:21

标签: c# reflection xml-serialization

我发现如果可序列化的字段/属性具有布尔类型的相应字段,其名称为字段/属性带有“Specified”后缀的名称,XmlSerializer有条件地从序列化过程中排除 Field / Property 。尼斯!

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

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

这会有用吗?

3 个答案:

答案 0 :(得分:2)

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

请参阅Attributes That Control XML Serialization

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

custom xml serialization

但是,正如此处Mixing custom and basic serialization?所述,一旦实现了IXmlSerializable,您就要负责所有类型的序列化逻辑。

答案 1 :(得分:2)

我将扩展 Martin Peck 的答案。 您可以避免使用“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;
        }
    }
}

答案 2 :(得分: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} it;

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

结果SOAP消息;

<advancedSearchRequests>
 <vehicleType>BIKE</vehicleType>
 <search>abc</search>
</advancedSearchRequest>