XmlSerializer, «Указанный» суффикс и IReflect - PullRequest
6 голосов
/ 24 ноября 2010

Я обнаружил, что если сериализуемое Поле / Свойство имеет соответствующее поле типа Логическое , имеющее в качестве имени Поле / Свойство имя с "Указанный суффикс XmlSerializer условно исключает, что Поле / Свойство из процесса сериализации.Отлично!

Итак, я хочу избежать определения этих полей и динамически добавлять их во время выполнения ...

Чтение этого , я нашел интересный интерфейс IReflect , который я могу использовать для «эмуляции» динамических полей, которые используются экземплярами XmlSerializer для исключения определенных полей.

Будет ли это работать?

Ответы [ 3 ]

3 голосов
/ 21 августа 2015

Я буду расширять ответ Мартин Пек . Вы можете избежать сериализации полей / свойств с указанным суффиксом. Вы должны определить эти "* Указанные" свойства в вашем классе и применить к ним [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 голосов
/ 24 ноября 2010

Если вы хотите взять под контроль сериализацию xml, у вас есть два варианта.Первый (что может быть здесь неуместно) - использовать атрибуты в пространстве имен System.Xml.Serialization для исключения свойств.Если вам действительно нужно определить, что сериализуется во время выполнения, это может быть не лучшим вариантом действий.

См. Атрибуты, управляющие сериализацией XML

Другой способсделать это, чтобы реализовать интерфейс IXmlSerializable в вашем классе и реализовать методы ReadXml и WriteXml.Это позволяет вам точно контролировать, как выглядит ваш xml.См. Этот вопрос для получения дополнительной информации:

настраиваемая сериализация xml

Однако, как уже упоминалось здесь Смешивание настраиваемой и базовой сериализации? после внедрения IXmlSerializableнесут ответственность за всю логику сериализации для вашего типа.

0 голосов
/ 12 марта 2019

Пример кода в качестве дополнения к предоставленному ответу;

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>
...