Сериализовать обнуляемое int

У меня есть класс с int, допускающим значение 9X_deserialize NULL? тип данных установлен для сериализации 9X_unserialize как xml-элемента. Есть ли способ настроить 9X_xml-file его так, чтобы сериализатор xml не сериализовал 9X_c#-language элемент, если значение равно нулю?

Я попытался 9X_c#-language добавить атрибут [System.Xml.Serialization.XmlElement 9X_c#-language (IsNullable = false)], но получаю исключение 9X_xml сериализации во время выполнения, в котором 9X_serialization говорится, что произошла ошибка, отражающая 9X_xml-file тип, потому что "IsNullable не может быть 9X_dot-net установлен значение false для типа, допускающего 9X_xml значение NULL. Рассмотрите возможность использования 9X_dot-net типа System.Int32 или удаления свойства 9X_visual-c# IsNullable из атрибута XmlElement ».

[Serializable] [System.Xml.Serialization.XmlRoot("Score", Namespace = "http://mycomp.com/test/score/v1")] public class Score { private int? iID_m; ... /// 
/// ///
 public int? ID { get { return iID_m; } set { iID_m = value; } } ... } 

Вышеупомянутый 9X_xml класс будет сериализован в:

 

Но для идентификаторов 9X_serialize с нулевым значением мне вообще не нужен 9X_serialize элемент идентификатора, в первую очередь 9X_c-sharp потому, что, когда я использую OPENXML в 9X_visual-c# MSSQL, он возвращает 0 вместо null для элемента, который 9X_visual-c# выглядит как

93
0
6
Общее количество ответов: 6

Ответ #1

Ответ на вопрос: Сериализовать обнуляемое int

XmlSerializer поддерживает шаблон ShouldSerialize{Foo}(), поэтому 9X_.net вы можете добавить метод:

public bool ShouldSerializeID() {return ID.HasValue;} 

Существует также 9X_xml-file шаблон {Foo}Specified - не уверен, поддерживает ли его 9X_serialize XmlSerializer.

155
5

  • @mark, если для члена (свойство / поле) `Foo` у вас также есть` public bool FooSpecified {get {...} set {...}} `, ...

Ответ #2

Ответ на вопрос: Сериализовать обнуляемое int

Я использую этот микро-шаблон для реализации 9X_visual-c# сериализации, допускающей значение NULL:

[XmlIgnore] public double? SomeValue { get; set; } [XmlAttribute("SomeValue")] // or [XmlElement("SomeValue")] [EditorBrowsable(EditorBrowsableState.Never)] public double XmlSomeValue { get { return SomeValue.Value; } set { SomeValue= value; } } [EditorBrowsable(EditorBrowsableState.Never)] public bool XmlSomeValueSpecified { get { return SomeValue.HasValue; } } 

Это 9X_serialize обеспечивает правильный интерфейс для пользователя 9X_dot-net без компромиссов и по-прежнему делает правильные 9X_c-sharp вещи при сериализации.

28
1

  • Поскольку SomeValue может иметь значение null ... publi ...

Ответ #3

Ответ на вопрос: Сериализовать обнуляемое int

Я нашел обходной путь, используя два свойства. Int? свойство 9X_serialisation с атрибутом XmlIgnore и свойством объекта, которое 9X_.net-framework сериализуется.

 /// 
/// Score db record ///
 [System.Xml.Serialization.XmlIgnore()] public int? ID { get { return iID_m; } set { iID_m = value; } } /// 
/// Score db record ///
 [System.Xml.Serialization.XmlElement("ID",IsNullable = false)] public object IDValue { get { return ID; } set { if (value == null) { ID = null; } else if (value is int || value is int?) { ID = (int)value; } else { ID = int.Parse(value.ToString()); } } } 

12
0

Ответ #4

Ответ на вопрос: Сериализовать обнуляемое int

Вау, спасибо, этот вопрос / ответ мне действительно 9X_dotnet помог. Мне нравится Stackoverflow.

Я сделал 9X_csharp то, что вы делаете выше, более общим. Все, что 9X_c# нам действительно нужно, это иметь Nullable 9X_csharp с немного другим поведением сериализации. Я 9X_csharp использовал Reflector для создания своего 9X_c# собственного Nullable и добавил кое-что 9X_serialization здесь и там, чтобы сериализация XML работала 9X_deserialize так, как мы хотим. Кажется, работает неплохо:

public class Nullable { public Nullable(T value) { _value = value; _hasValue = true; } public Nullable() { _hasValue = false; } [XmlText] public T Value { get { if (!HasValue) throw new InvalidOperationException(); return _value; } set { _value = value; _hasValue = true; } } [XmlIgnore] public bool HasValue { get { return _hasValue; } } public T GetValueOrDefault() { return _value; } public T GetValueOrDefault(T i_defaultValue) { return HasValue ? _value : i_defaultValue; } public static explicit operator T(Nullable i_value) { return i_value.Value; } public static implicit operator Nullable(T i_value) { return new Nullable(i_value); } public override bool Equals(object i_other) { if (!HasValue) return (i_other == null); if (i_other == null) return false; return _value.Equals(i_other); } public override int GetHashCode() { if (!HasValue) return 0; return _value.GetHashCode(); } public override string ToString() { if (!HasValue) return ""; return _value.ToString(); } bool _hasValue; T _value; } 

Вы 9X_.net теряете возможность иметь членов как int? и 9X_c#-language так далее (вместо этого нужно использовать 9X_unserialize Nullable ), но в остальном все поведение остается прежним.

6
1

  • Это вызывает у меня исключение System.ExecutionEngineException в XmlSerializer ...

Ответ #5

Ответ на вопрос: Сериализовать обнуляемое int

К сожалению, описываемое вами поведение 9X_dotnet точно задокументировано как таковое в документации 9X_csharp для XmlElementAttribute.IsNullable.

1
0

Ответ #6

Ответ на вопрос: Сериализовать обнуляемое int

Очень полезная публикация очень помогла.

Я 9X_deserialize решил использовать версию Скотта с типом 9X_xml данных Nullable (Of T), однако опубликованный 9X_c#.net код по-прежнему сериализует элемент Nullable, когда 9X_c# он имеет значение Null, хотя и без атрибута 9X_csharp «xs: nil = 'true'».

Мне нужно было заставить 9X_serialisation сериализатор полностью удалить тег, поэтому 9X_c-sharp я просто реализовал IXmlSerializable в структуре 9X_dotnet (это в VB, но вы понимаете):

 '---------------------------------------------------------------------------- ' GetSchema '---------------------------------------------------------------------------- Public Function GetSchema() As System.Xml.Schema.XmlSchema Implements System.Xml.Serialization.IXmlSerializable.GetSchema Return Nothing End Function '---------------------------------------------------------------------------- ' ReadXml '---------------------------------------------------------------------------- Public Sub ReadXml(ByVal reader As System.Xml.XmlReader) Implements System.Xml.Serialization.IXmlSerializable.ReadXml If (Not reader.IsEmptyElement) Then If (reader.Read AndAlso reader.NodeType = System.Xml.XmlNodeType.Text) Then Me._value = reader.ReadContentAs(GetType(T), Nothing) End If End If End Sub '---------------------------------------------------------------------------- ' WriteXml '---------------------------------------------------------------------------- Public Sub WriteXml(ByVal writer As System.Xml.XmlWriter) Implements System.Xml.Serialization.IXmlSerializable.WriteXml If (_hasValue) Then writer.WriteValue(Me.Value) End If End Sub 

Я предпочитаю 9X_deserialize этот метод использованию шаблона Specified 9X_c#-language (foo), поскольку для этого требуется добавить 9X_serialization множество избыточных свойств к моим объектам, тогда 9X_c-sharp как использование нового типа Nullable требует 9X_dotnet лишь повторного ввода свойств.

1
0