Web Services 如何使用svcutil从使用限制隐藏元素的Web服务生成C# WCF代理?

5vf7fwbs  于 2022-11-15  发布在  C#
关注(0)|答案(1)|浏览(162)

我正在创建一个Web服务的客户端,它或多或少不受我的控制。

<xs:complexType name="A">
    <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="1" name="element1" type="xs:string" />
        <xs:element minOccurs="0" maxOccurs="1" name="element2" type="xs:string" />
    </xs:sequence>
</xs:complexType>

<xs:complexType name="B">
    <xs:complexContent>
        <xs:restriction base="A">
            <xs:sequence>
                <xs:element minOccurs="1" maxOccurs="1" name="element2" type="xs:string" />
            </xs:sequence>
        </xs:restriction>
    </xs:complexContent>
</xs:complexType>

简言之,我们有一个包含所有元素的对象A,服务有几个基于A的类型,但有一些限制,因此继承的类型通常比基类型小--这里以类型B为例。
在架构查看器(如Visual Studio 2010、SoapUI等)中,这看起来与预期一致。A有2个元素,而B只有1个(=元素2)。
通过使用svcutil,我得到了类型A和B中的完整元素集,或者在使用选项时,我得到了如下错误消息:
错误:无法导入命名空间“http://tempuri.org/XMLSchema.xsd”中的类型“B”。不支持通过限制派生的复杂类型。请更改架构以便这些类型可以Map到数据协定类型,或者使用ImportXmlType或使用其他序列化程序。
在继承的类型中隐藏字段/属性不是我喜欢的做法/道路,但如果我不能让提供程序更改WSDL,似乎我必须这样做。

是否有替代svcutil的方法可以正确处理此问题,或者我是否必须手动编写代理代码?
更新1

正如John Saunders所指出的,我没有展示svcutil的建议的结果。这部分是为了保持文章简短......但这里有:

svcutil schema.xsd /importXmlTypes /datacontonly结果为:

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="A", Namespace="http://tempuri.org/XMLSchema.xsd")]
public partial class A : object, System.Runtime.Serialization.IExtensibleDataObject
{

    private System.Runtime.Serialization.ExtensionDataObject extensionDataField;

    private string element1Field;

    private string element2Field;

    public System.Runtime.Serialization.ExtensionDataObject ExtensionData
    {
        get
        {
            return this.extensionDataField;
        }
        set
        {
            this.extensionDataField = value;
        }
    }

    [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false)]
    public string element1
    {
        get
        {
            return this.element1Field;
        }
        set
        {
            this.element1Field = value;
        }
    }

    [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false)]
    public string element2
    {
        get
        {
            return this.element2Field;
        }
        set
        {
            this.element2Field = value;
        }
    }
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Xml.Serialization.XmlSchemaProviderAttribute("ExportSchema")]
[System.Xml.Serialization.XmlRootAttribute(IsNullable=false)]

public partial class B : object, System.Xml.Serialization.IXmlSerializable
{

    private System.Xml.XmlNode[] nodesField;

    private static System.Xml.XmlQualifiedName typeName = new System.Xml.XmlQualifiedName("B", "http://tempuri.org/XMLSchema.xsd");

    public System.Xml.XmlNode[] Nodes
    {
        get
        {
            return this.nodesField;
        }
        set
        {
            this.nodesField = value;
        }
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
        this.nodesField = System.Runtime.Serialization.XmlSerializableServices.ReadNodes(reader);
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        System.Runtime.Serialization.XmlSerializableServices.WriteNodes(writer, this.Nodes);
    }

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public static System.Xml.XmlQualifiedName ExportSchema(System.Xml.Schema.XmlSchemaSet schemas)
    {
        System.Runtime.Serialization.XmlSerializableServices.AddDefaultSchema(schemas, typeName);
        return typeName;
    }
}

在XML级别上工作是不可取的,这将迫使我们编写一个 Package 器。从getgo手工编写代理更容易。

svcutil schema.xsd /serializer:XmlSerializer /datacontonly给出下面的错误,这也是我要求使用替代工具的原因。

svcutil schema.xsd /序列化程序:XmlSerializer /数据压缩程序错误:无法导入命名空间“http://tempuri.org/XMLSchema.xsd”中的类型“B”。不支持通过限制派生的复杂类型。请更改架构以便这些类型可以Map到数据协定类型,或者使用ImportXmlType或使用其他序列化程序。
如果使用/dataContractOnly选项导入数据协定类型并收到此错误消息,请考虑改用xsd.exe。在服务协定上应用XmlSerializerFormatAttribute特性后,可以在Windows Communication Foundation中使用xsd.exe生成的类型。或者,请考虑使用/importXmlTypes选项将这些类型作为XML类型导入,以便与服务协定上的DataContractFormatAttribute属性一起使用。
使用xsd schema.xsd /c给出一个继承A而不隐藏element 1的类型B:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/XMLSchema.xsd")]
[System.Xml.Serialization.XmlRootAttribute("request", Namespace="http://tempuri.org/XMLSchema.xsd", IsNullable=false)]
public partial class B : A {
}

/// <remarks/>
[System.Xml.Serialization.XmlIncludeAttribute(typeof(B))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/XMLSchema.xsd")]
public partial class A {

    private string element1Field;

    private string element2Field;

    /// <remarks/>
    public string element1 {
        get {
            return this.element1Field;
        }
        set {
            this.element1Field = value;
        }
    }

    /// <remarks/>
    public string element2 {
        get {
            return this.element2Field;
        }
        set {
            this.element2Field = value;
        }
    }
}
oyxsuwqo

oyxsuwqo1#

错误消息会告诉您使用/importXmlTypes参数,或变更为使用XmlSerializer。从说明:
/importXmlTypes -将数据协定序列化程序配置为将非数据协定类型作为IXmlSerializable类型导入。

/serializer:XmlSerializer -生成使用XmlSerializer进行序列化与反序列化得数据类型

相关问题