【发布时间】:2014-01-26 20:42:32
【问题描述】:
我有一个 xsd 架构,其中包含 int 类型的可选元素(minOccurs=0、maxOccurs=1)。该元素未定义为 nillable。在数据模型中,我想将其映射到 .net 类型 Nullable<int> 的字段,其中 null 值应对应于 xml 中省略的元素。
但是,使用XmlSerializer,我似乎必须在数据模型中用[XmlElement IsNullable=true] 声明一个可为空的字段。如果我设置IsNullable=false,我会得到异常“IsNullable 可能不会设置为 Nullable 类型的 'false'。”IsNullable 可能不会设置为 Nullable 类型的 'false'。考虑使用 'System.Int32' 类型或从 XmlElement 属性中删除 IsNullable 属性。“但如果我理解正确,设置 IsNullable=true(或忽略该属性)会隐式地将元素设置为 nillable,因此更改架构。
这是架构优先的设计,所以我不能只在架构中的元素中添加“nillable”。
如何将可为空的 .net 类型映射到不可为空的 xml 元素?
(我知道在序列化为 xml 时可以通过在数据模型中使用 XxxSpecified 属性省略 nil-elements,但据我所知,这种方法仍然需要向 xsd 架构添加 nillable。)
编辑:感谢 cmets,我现在更好地理解了这个问题。实际上有两个不同的问题:
像 xsd.exe 这样的架构到代码生成器会创建一个不可为空的 如果架构元素不可为空,则输入生成的模型 (即使它是可选的)。我可以覆盖它吗(使用任何已知的代码 生成器),所以我在生成的代码中获得了可为空的类型?
XmlSerializer 要求数据模型中的可为空类型具有
[XmlElement IsNullable=true],表示模型隐式添加 'nillable' 到模式。我可以避免这种情况吗?
【问题讨论】:
-
到底是什么问题?您是从代码生成 xsd,反之亦然,还是两者都不生成?
-
我正在从 XSD 生成代码。我的问题是:我不知道是否可以将 C# 映射中的可为空类型映射到 xml 中的非 nillabale 元素。由于这是架构优先的设计,我不能只在架构中的元素中添加“nillable”。
-
呃。我没有把我的问题说清楚。您是使用自动工具 XSD.exe 从 XSD 生成代码,还是手动编写代码?如果是前者,您唯一的解决方案是添加某种预处理或后处理步骤,因为 XSD.exe 不支持您想要的。如果是后者,您的选择范围会更广。
-
其实我是用Xsd2Code来生成代码的,所以我可以在一定程度上修改代码的生成方式。但是我不确定如何在不引入可空元素的情况下使用手工编写的代码来解决这个问题。
-
您是否考虑过使用 FormatterServices 对象和 System.Reflection 命名空间编写自己的序列化程序?我有一个例子,但它不是微不足道的。我已经花了很多年的时间来解决这个问题,但那是为我自己的。如果您有特定要求,则需要对其进行描述。