【问题标题】:xsd.exe just emits a single Object field when generating code from XSD从 XSD 生成代码时,xsd.exe 只发出一个 Object 字段
【发布时间】:2017-05-26 03:51:35
【问题描述】:

我有一个定义如下的 XSD(我匿名了类型名称),你总是会得到一个 <response> 元素:

<xsd:element name="response">
    <xsd:complexType>
        <xsd:annotation>
            <xsd:documentation>
                Root element of the all response XML's
            </xsd:documentation>
        </xsd:annotation>
        <xsd:sequence>
        <xsd:choice>
            <xsd:choice>
                 <xsd:element name="TypeA" type="TypeAType" />
                 <xsd:element name="TypeB" type="TypeBType" />
                 <xsd:element name="TypeC" type="TypeCType" />
            </xsd:choice>

            <xsd:element name="error" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation>
                        In case of error this will contain detailed error information
                        and no other sibling elements will exist.
                        If the request is successful this element will not exist.
                    </xsd:documentation>
                </xsd:annotation>
            </xsd:element>
        </xsd:choice>
        </xsd:sequence>
    </xsd:complexType>
</xsd:element>

当我使用 XSD.exe (Visual 2013) 自动生成 C# 代码时,我得到了这个:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute("response", Namespace="", IsNullable=false)]
public partial class response {

    private object itemField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("TypeA", typeof(TypeAType))]
    [System.Xml.Serialization.XmlElementAttribute("TypeB", typeof(TypeBType))]
    [System.Xml.Serialization.XmlElementAttribute("TypeC", typeof(TypeCType))]
    [System.Xml.Serialization.XmlElementAttribute("error", typeof(string))]
    public object Item {
        get {
            return this.itemField;
        }
        set {
            this.itemField = value;
        }
    }
}

只有一个 Object 字段。甚至没有一个枚举/值来告诉我它对应于哪个元素/类型,我必须检查类型或强制转换。在过去,XSD.exe 生成了一些更加用户友好的东西。例如每种类型的字段TypeAType typeAField; string errorField;

我在这里的主要抱怨是error 只是一个字符串。所以我判断是否有错误的唯一方法是查看Item 是否为string。感觉真的很笨重。

谁能说明为什么 XSD.exe 会以这种方式与此 XSD 一起工作,以及是否有其他方法可以哄骗它。

【问题讨论】:

    标签: .net visual-studio visual-studio-2013 xsd xsd.exe


    【解决方案1】:

    如果choice 中元素的类型不同,xsd.exe 只会生成object 类型的单个属性,或者它们的公共基类(如果有的话)。如果某些元素具有相同的类型,xsd.exe 会生成一个附加字段和一个枚举来区分这些元素。这是 MSDN 上的文档:Choice Element Binding Support

    我相信按类型区分更习惯用语,更 DRY(额外的枚举只会重复 .NET 类型系统中已经存在的信息)并且更易于使用(只需设置元素的属性而不是额外的类型属性,加上if (x.Item is string) ... 似乎比if (x.ItemElementName == ItemChoiceType.TypeA) ... 更容易)。但是,如果您真的想要枚举,您可以在 choice 中引入一个额外的虚拟元素,该元素与其他选项之一具有相同的类型。

    【讨论】:

    • 你介意解释一下吗,举个例子。 “额外的虚拟元素”?这是我讨厌使用 xsd.exe 的另一个原因。元素绑定现在根本不像以前在这些灰色区域中那样有用。如果我必须手动为托管代码创建一个枚举,那么它就违背了使用它的全部目的。
    • 添加另一个与其他元素具有相同类型的虚拟XmlElementAttribute,例如[System.Xml.Serialization.XmlElementAttribute("TypeC2", typeof(TypeCType))]。这会强制 xsd.exe 生成附加字段和枚举。但正如我所说,我建议坚持使用基于类型的方法。 C# 7 (VS 2017) 通过模式匹配使使用生成的代码变得更加容易:if (x.Item is string error) ...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-28
    相关资源
    最近更新 更多