如何使用 .NET XmlSerializer 使值类型可以为空? [英] How to make a value type nullable with .NET XmlSerializer?

查看:19
本文介绍了如何使用 .NET XmlSerializer 使值类型可以为空?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有这个对象:

[Serializable]
public class MyClass
{
    public int Age { get; set; }
    public int MyClassB { get; set; }
}
[Serializable]
public class MyClassB
{
    public int RandomNumber { get; set; }
}

XmlSerializer 将像这样序列化对象:

The XmlSerializer will serialize the object like that:

<MyClass>
    <Age>0</age>
    <MyClassB>
        <RandomNumber>4234</RandomNumber>
    </MyClassB>
</MyClass>

如何使属性 Age 可以为空?IE:当属性年龄小于 0 时不序列化它?

How can I made the property Age nullable? IE: to not serialize the property Age when it's under 0?

我尝试使用 Nullable,但它会像这样序列化我的对象:

I tried with the Nullable, but it serialize my object like that:

<MyClass>
    <Age d5p1:nil="true" />
    <MyClassB>
        <RandomNumber>4234</RandomNumber>
    </MyClassB>
</MyClass>    

通过阅读 MSDN 文档,我发现了这一点:

By reading the MSDN documentation I found this:

您不能将 IsNullable 属性应用于键入为值类型的成员,因为值类型不能包含 nullNothingnullptra 空引用(在 Visual Basic 中为 Nothing).此外,对于可为空的值类型,您不能将此属性设置为 false.当此类类型为 nullNothingnullptra 空引用(在 Visual Basic 中为 Nothing)时,将通过将 xsi:nil 设置为 true 来序列化它们.

You cannot apply the IsNullable property to a member typed as a value type because a value type cannot contain nullNothingnullptra null reference (Nothing in Visual Basic). Additionally, you cannot set this property to false for nullable value types. When such types are nullNothingnullptra null reference (Nothing in Visual Basic), they will be serialized by setting xsi:nil to true.

来源:http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlelementattribute.isnullable.aspx

我知道不能将值类型设置为 null.值类型总是被设置为某物.序列化不能根据它的当前值来决定是否序列化它.

I understand a value type can't be set to null. A valuetype is always set to something. The serialization can't make the decision to serialize it or not based on it's current value.

我尝试使用这些属性,但没有成功.我尝试创建一个 agecontainer 对象并使用属性操作它的序列化,但没有成功.

I tried with the attributes, but it didn't work out. I tried creating an agecontainer object and manipulate it's serialization with attributes, but it didn't work out.

我真正想要的是:

<MyClass>
    <MyClassB>
        <RandomNumber>4234</RandomNumber>
    </MyClassB>
</MyClass>

当属性年龄低于 0(零)时.

When the property Age is below 0 (zero).

看起来您必须实现自定义序列化.

Looks like you'll have to implement custom serialization.

是的,我也这么认为,但我想没有它就离开.

Yeah, that's what I though too, but I'd like to get away without it.

在应用中,对象要复杂得多,我不想自己处理序列化.

In the application, the object is much more complex, and I would like to not handle the serialization myself.

推荐答案

我刚刚发现了这个.XmlSerialier 查找 XXXSpecified 布尔属性以确定是否应包含它.这应该可以很好地解决问题.

I just discovered this. XmlSerialier looks for a XXXSpecified boolean property to determine if it should be included. This should solve the problem nicely.

[Serializable]
public class MyClass
{
  public int Age { get; set; }
  [XmlIgnore]
  public bool AgeSpecified { get { return Age >= 0; } }
  public int MyClassB { get; set; }
}

[Serializable]
public class MyClassB
{
  public int RandomNumber { get; set; }
}

证明:

static string Serialize<T>(T obj)
{
  var serializer = new XmlSerializer(typeof(T));
  var builder = new StringBuilder();
  using (var writer = new StringWriter(builder))
  {
    serializer.Serialize(writer, obj);
    return builder.ToString();
  }
}

static void Main(string[] args)
{
  var withoutAge = new MyClass() { Age = -1 };
  var withAge = new MyClass() { Age = 20 };

  Serialize(withoutAge); // = <MyClass><MyClassB>0</MyClassB></MyClass>
  Serialize(withAge); // = <MyClass><Age>20</Age><MyClassB>0</MyClassB></MyClass>
}


编辑:是的,这是一个记录在案的功能.请参阅 MSDN 条目 XmlSerializer


Edit: Yes, it is a documented feature. See the MSDN entry for XmlSerializer

另一种选择是使用特殊模式创建 XmlSerializer 识别的布尔字段,并将 XmlIgnoreAttribute 应用于该字段.该模式以propertyNameSpecified 的形式创建.例如,如果有一个名为MyFirstName"的字段,您还将创建一个名为MyFirstNameSpecified"的字段,以指示 XmlSerializer 是否生成名为MyFirstName"的 XML 元素.

Another option is to use a special pattern to create a Boolean field recognized by the XmlSerializer, and to apply the XmlIgnoreAttribute to the field. The pattern is created in the form of propertyNameSpecified. For example, if there is a field named "MyFirstName" you would also create a field named "MyFirstNameSpecified" that instructs the XmlSerializer whether to generate the XML element named "MyFirstName".

这篇关于如何使用 .NET XmlSerializer 使值类型可以为空?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆