微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

.net – 将可空类型序列化为可选的非可贵元素

我有一个xsd模式,其中包含int类型的可选元素(minOccurs = 0,maxOccurs = 1).元素未定义为可为空.在数据模型中,我想将其映射到.net类型Nullable< int>的字段,其中空值应对应于xml中省略的元素.

但是,使用XmlSerializer,似乎我必须使用[XmlElement IsNullable = true]在数据模型中声明一个可为空的字段.如果我设置IsNullable = false,我得到异常“对于Nullable类型,IsNullable可能不会被设置为’false’.”对于Nullable类型,IsNullable可能不会设置为’false’.考虑使用’system.int32’类型或从XmlElement属性删除IsNullable属性.“但是如果我理解正确,设置IsNullable = true(或保留属性)隐式地将元素设置为nillable,从而更改模式.

这是架构优先设计,所以我不能只将’nillable’添加到架构中的元素.

如何将可空的.net类型映射到不可为空的xml元素?

(我知道在使用数据模型中的XxxSpecified属性序列化到xml时我可以省略nil-elements,但据我所知,这种方法仍然需要向xsd模式添加nillable.)

编辑:感谢评论,我现在更好地理解问题.实际上有两个不同的问题:

> xsd.exe之类的模式到代码生成器会创建一个不可为空的代码
如果架构元素不可为空,则键入生成的模型
(即使它是可选的).我可以覆盖它(使用任何已知的代码
生成器)所以我在生成代码中得到可空类型?
> XmlSerializer需要数据模型中的可空类型
[XmlElement IsNullable = true],表示模型隐式添加
‘nillable’到架构.我可以避免这个吗?

解决方法

我前段时间也遇到过这个问题.我通过引入处理序列化逻辑的附加属性解决它.

>首先,使用[XmlIgnore]属性标记原始属性,以将其从序列化/反序列化中排除.

// Mark your original property from serialization/deserialization logic
[XmlIgnore]
public int? OriginalProperty { get; set; }

>然后添加附加属性并使用[XmlElement(“YourElementName”)]属性标记它以处理序列化逻辑.

// Move serialization logic to additional string property
[XmlElement("OriginalPropertyXmlElement")]
public string OriginalPropertyAsstring
{
    get
    {
        //...
    }
    set
    {
        //...
    }
}

>在反序列化时,它将:

set
{
    // Check the field existence in xml
    if (string.IsNullOrEmpty(value))
    {
        // Set the original property to null
        this.OriginalProperty = default(int?);
    }
    else
    {
        // Get value from xml field
        this.OriginalProperty = int.Parse(value);
    }
}

>序列化:

get
{
    if (this.OriginalProperty.HasValue)
    {
        // Serialize it
        return this.OriginalProperty.ToString();
    }
    else
    {
        // Don't serialize it
        return null;
    }
}

>示例可能如下所示:

[XmlRoot("scene")]
public class Scene
{
    [XmlIgnore]
    public int? ParentId { get; set; }

    [XmlElement("parent_id")]
    public string ParentIdAsstring
    {
        get
        {
            return this.ParentId.HasValue ? this.ParentId.ToString() : null;
        }

        set
        {
            this.ParentId = !string.IsNullOrEmpty(value) ? int.Parse(value) : default(int?);
        }
    }
}

它非常简单,您不必编写自己的序列化程序,也不必破解xsd或其他东西.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。