XmlSerializer, “Specified” suffix and IReflect

后端 未结 3 1824
清酒与你
清酒与你 2021-01-02 15:06

I\'ve discovered that if a serializable Field/Property has a corresponding field of type Boolean having as a name the Field/Property name with \"S

相关标签:
3条回答
  • 2021-01-02 15:28

    I will extend answer of Martin Peck. You can avoid serialization of the fields/properties with "Specified" suffix. You should define that "*Specified" properties in your class and apply [XmlIgnoreAttribute()] to them.

    Here is an example:

    [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 讨论(0)
  • 2021-01-02 15:29

    If you want to take control of your xml serialization then you have two options. The first (which might not be appropriate here) it to use the attributes in the System.Xml.Serialization namespace to exclude properties. If you really need to do determine what gets serialized at runtime this might not be the best course of action.

    See Attributes That Control XML Serialization

    The other way to do this is to implement the IXmlSerializable interface on your class and implement the ReadXml and WriteXml methods. This allows you to take control of exactly how your xml looks. See this question for additional info:

    custom xml serialization

    However, as mentioned here Mixing custom and basic serialization? once you implement IXmlSerializable you are responsible for all the serialization logic for your type.

    0 讨论(0)
  • 2021-01-02 15:31

    Code sample as an extension to the provided answer;

    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>
    

    Generated .net SOAP client class

    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");
            }
        }
    
    }
    

    You can set "vehicleTypeFieldSpecified" = {true/false} to {serialize/omit} it;

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

    Resulting SOAP message;

    <advancedSearchRequests>
     <vehicleType>BIKE</vehicleType>
     <search>abc</search>
    </advancedSearchRequest>
    
    0 讨论(0)
提交回复
热议问题