Интересно, может ли кто-нибудь помочь со следующим.
Я изучаю проблему, которую мы обнаружили в нашей кодовой базе. У нас есть модель на C#, созданная на основе xsd, и внутри результирующей модели есть перечисления. Однако XML-код, который нам нужно десериализовать (сгенерированный третьей стороной), не содержит значений для всех свойств, например. Местами допускаются нули.
Для свойств, которые являются перечислениями, нулевое значение в XML-файле десериализуется в первое значение перечисления. Я уверен, что с помощью библиотек JSON можно было бы установить нулевую обработку с помощью параметров сериализации, но я еще не нашел способа справиться с этим с помощью типов сериализации .net xml.
Кто-нибудь знает, как это сделать, чтобы мне не приходилось вручную редактировать модель, сгенерированную из xsd, и чтобы это поведение можно было применить ко всей обработке перечислений? Я не вижу никаких вариантов в типах или методах, которые могли бы вызвать такое поведение.
В настоящее время я рассматриваю возможность изменения модели, поскольку это может быть приемлемо, поскольку это модель с версиями, поэтому изменения сопровождаются механизмом управления версиями, а это означает, что не должно возникнуть необходимости повторно создавать модель (с возможностью редактирования вручную). . Хотя делать это для каждой модели, для каждой версии, для каждого свойства перечисления не является предпочтительным подходом.
Пример ниже (обратите внимание, я опустил ненужные части модели).
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:iso:std:iso:20022:tech:xsd:head.001.001.02")]
public partial class PostalAddress24
{
public AddressType3Choice? AdrTp {
get {
return this.adrTpField;
}
set {
this.adrTpField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:iso:std:iso:20022:tech:xsd:head.001.001.02")]
public partial class AddressType3Choice {
private object itemField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Cd", typeof(AddressType2Code))]
[System.Xml.Serialization.XmlElementAttribute("Prtry", typeof(GenericIdentification30))]
public object Item {
get {
return this.itemField;
}
set {
this.itemField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
[System.SerializableAttribute()] [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:iso:std:iso:20022:tech:xsd:head.001.001.02")]
public enum AddressType2Code {
/// <remarks/>
ADDR,
/// <remarks/>
PBOX,
/// <remarks/>
HOME,
/// <remarks/>
BIZZ,
/// <remarks/>
MLTO,
/// <remarks/>
DLVY,
}
В XML-файле указан почтовый адрес, указанный ниже, поэтому указана страна (ctry), но AdrTp не указан.
<PstlAdr>
<Ctry>GB</Ctry>
</PstlAdr>
The deserialisation of the xml to the model is presently done using the standard XmlSerializer class.
If anyone has solved this please do let me know as it'll short cut further investigations.
Прежде всего, XML отличает значение null (xsi:nil) от неуказанного значения (отсутствие узла в xml). В вашем случае значение не указано.
Чтобы узнать, присутствовал ли узел в xml, используйте свойства *Specified
, например:
[XmlIgnore]
public bool AdrTpSpecified { get; set; }
XmlSerializer
устанавливает свойства *Specified
в значение true, когда он читает XML и находит связанный узел. Когда он записывает XML, он использует свойства *Specified
, чтобы определить, следует ли создавать связанный узел.
Спасибо @ Sinus32. Хорошо, это не мое «идеальное» решение. Это позволило бы избежать присвоения значений по умолчанию перечислениям, когда значение отсутствует в источнике, но я понимаю, что это невозможно. Ваше решение будет работать, поскольку я сопоставляю автоматически сгенерированную модель с более лаконичной внутренней моделью.