Сериализовать обнуляемое 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# выглядит как
Ответ #1
Ответ на вопрос: Сериализовать обнуляемое int
XmlSerializer поддерживает шаблон ShouldSerialize{Foo}()
, поэтому 9X_.net вы можете добавить метод:
public bool ShouldSerializeID() {return ID.HasValue;}
Существует также 9X_xml-file шаблон {Foo}Specified
- не уверен, поддерживает ли его 9X_serialize XmlSerializer.
- @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 вещи при сериализации.
- Поскольку 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());
}
}
}
Ответ #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
- Это вызывает у меня исключение System.ExecutionEngineException в XmlSerializer ...
Ответ #5
Ответ на вопрос: Сериализовать обнуляемое int
К сожалению, описываемое вами поведение 9X_dotnet точно задокументировано как таковое в документации 9X_csharp для XmlElementAttribute.IsNullable.
Ответ #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 лишь повторного ввода свойств.
-
14
-
3
-
2
-
2
-
2
-
2
-
1
-
5
-
6
-
1
-
4
-
17
-
6
-
5
-
2
-
5
-
2
-
4
-
2
-
3
-
5
-
4
-
2
-
3
-
5
-
2
-
2
-
2
-
1
-
2
-
2
-
6
-
3
-
5
-
3
-
10
-
3
-
9
-
6
-
7
-
3
-
8
-
9
-
5
-
10
-
8
-
2
-
6
-
6
-
4