【问题标题】:how to generate custom collection type in .Net from WSDL?如何在 .Net 中从 WSDL 生成自定义集合类型?
【发布时间】:2009-02-20 16:27:28
【问题描述】:

我正在运行一个自定义应用程序,该应用程序导入 WSDL 并生成 C# 源代码,使用 WSDLImporter 类来读取合同。

XSD 序列类型被转换为本机数组。为了能够生成自定义集合类型,我可以设置哪些选项?

架构:

<xs:complexType name="getAllSourcesResponse">
    <xs:sequence>
        <xs:element maxOccurs="unbounded" minOccurs="0" 
            name="return" type="tns:Source"/>
    </xs:sequence>
</xs:complexType>

变成代码:

public partial class getAllSourcesResponse
{
    [System.Xml.Serialization.XmlElementAttribute("return",
        Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public PaymentSource[] @return;

    public getAllSourcesResponse()
    {
    }

    public getAllSourcesResponse(Source[] @return)
    {
        this.@return = @return;
    }
}

我查看了 SvcUtil.exe 代码,它似乎执行以下操作,但它似乎对我的应用程序生成的代码没有任何影响。

WsdlImporter importer = ... 

XsdDataContractImporter contractImporter = 
    new XsdDataContractImporter(codeCompileUnit); 

ImportOptions importOptions = new ImportOptions();
importOptions.ReferencedCollectionTypes.Add(
    typeof(System.Collections.Generic.IList<>)); 

contractImporter.Options = importOptions; 

importer.State.Add(typeof(XsdDataContractImporter), contractImporter); 

@CasperOne,这个架构 sn-p

<xs:complexType name="getClassesForPackageResponse">
     <xs:sequence>
         <xs:element maxOccurs="unbounded" minOccurs="0" name="return" type="xs:string"/>
     </xs:sequence>
 </xs:complexType>

生成一个字符串[]类型:

public partial class getClassesForPackageResponse
{
    public string[] @return;
    public getClassesForPackageResponse() {}

    public getClassesForPackageResponse(string[] @return)
    {    this.@return = @return;    }
}

这不会导致字符串集合使用List:

ImportOptions importOptions = new ImportOptions();
importOptions.ReferencedCollectionTypes.Add(
    typeof(System.Collections.Generic.List<string>));

【问题讨论】:

    标签: c# .net collections wsdl svcutil.exe


    【解决方案1】:

    首先,我认为您需要指出一个集合实现,而不仅仅是接口,这意味着List&lt;T&gt; 而不是IList&lt;T&gt;(尽管您当然可以尝试使用接口)。

    其次,需要指定类型参数T:

    ImportOptions importOptions = new ImportOptions();
    
    importOptions.ReferencedCollectionTypes.Add(
        typeof(System.Collections.Generic.List<getAllSourcesResponse>));
    

    事实上,您传递的是开放的泛型类型,当导入器尝试解析集合时,它不会与任何内容匹配。

    【讨论】:

    • 进行转换的工具不知道 WSDL 中使用的类型。我无法指定“List”,因为 getAllSourcesResponse 不是有效的类型或命名空间,它会导致编译错误。
    • 我也试过“System.Collections.Generic.List”,但在生成的代码中我仍然得到“string[]”,而不是“List
    • @janya:好吧,为什么不获取 getAllSourcesResponse ^first^ 的架构并获取其类型表示,然后导入合约定义?
    • @casperOne:确实如此,我会这样做,谢谢。任何想法为什么将 List 添加到 ReferencedCollectionTypes 仍然会在生成的代码中获得 string[]?
    • @janya:因为它无法将字符串类型与架构定义匹配。如果它是一个字符串元素序列,那么它将被用作一个字符串,但它是一个 getAllSourcesResponse 元素序列。
    【解决方案2】:

    在试图弄清楚如何在 Mono 的 WSDL 导入器中执行此操作时偶然发现了这一点。

    在阅读了一些 MSDN 文档并对此进行了一些尝试之后,我使用 .NET 4.5 让它像这样工作:

        var importer = new WsdlImporter (mset);
        var xsdImporter = new XsdDataContractImporter ();
        var options = new ImportOptions ();
        options.ReferencedCollectionTypes.Add (typeof (LinkedList<>));
        xsdImporter.Options = options;
        importer.State.Add (typeof (XsdDataContractImporter), xsdImporter);
    

    您还可以指定特定的通用实例类型,例如List&lt;int&gt;

    这也记录在这里:http://msdn.microsoft.com/en-us/library/aa702680.aspx

    【讨论】:

      猜你喜欢
      • 2011-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多