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

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

问题描述

让我们假设我有这样的对象:

Let's suppose I have this object:

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

我怎样才能取得的财产为空的时代? IE:不序列化属性年龄时,它的下0

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

我试图与可空,但我的序列化对象,这样的:

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属性适用于类型为值类型的成员,因为值类型不能包含nullNothingnullptrnull引用(在Visual Basic中为Nothing)。此外,您不能将此属性设置为false,空值类型。零为true:当这种类型nullNothingnullptrnull引用(在Visual Basic中为Nothing),他们将通过设置XSI被序列化。

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.

来源:<一个href=\"http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlelementattribute.isnullable.aspx\">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>
}



修改:是的,它是一个记录的功能。请参阅的XmlSerializer MSDN进入>

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

另一种选择是使用一个特殊的图案,以创建由XmlSerializer的识别的布尔字段,并以XmlIgnoreAttribute应用到域。在propertyNameSpecified的形式产生的图案。例如,如果有一个名为字段MyFirstName你会也创建一个名为MyFirstNameSpecified字段,指示XmlSerializer的是否生成命名为XML元素MyFirstName

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天全站免登陆