Как создать пользовательский тип коллекции в .Net из WSDL? - PullRequest
1 голос
/ 20 февраля 2009

Я запускаю пользовательское приложение, которое импортирует 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, этот фрагмент схемы

<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>));

Ответы [ 2 ]

2 голосов
/ 20 февраля 2009

Во-первых, я считаю, что вам нужно указать реализацию коллекции, а не только интерфейс, так что это означает List<T> вместо IList<T> (хотя вы, конечно, можете попробовать это с интерфейсом).

Во-вторых, вам нужно указать параметр типа T:

ImportOptions importOptions = new ImportOptions();

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

Как и раньше, вы передавали открытый универсальный тип, который не будет совпадать ни с чем, когда импортер пытается разрешить коллекцию.

1 голос
/ 02 октября 2012

Просто наткнулся на это, пытаясь понять, как это сделать в импортере WSDL в Mono.

Прочитав несколько документов 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<int>.

Это также задокументировано здесь: http://msdn.microsoft.com/en-us/library/aa702680.aspx

...