加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 23:16:41 所属栏目:百科 来源:网络整理
导读:我有一个xsd模式,其中包含int类型的可选元素(minOccurs = 0,maxOccurs = 1).元素未定义为可为空.在数据模型中,我想将其映射到.net类型Nullable int的字段,其中空值应对应于xml中省略的元素. 但是,使用XmlSerializer,似乎我必须使用[XmlElement IsNullable =
我有一个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或其他东西.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读