Howto verwenden svcutil zu generieren, C# - WCF-proxy, von einem web-service, verwendet die Beschränkung auf Elemente ausblenden?

Ich bin erstellen von einem client an einen web-Dienst, der mehr oder weniger außerhalb meiner Kontrolle. Hier ist ein Vereinfachtes Beispiel von dem schema:

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

Kurz, wir haben Einen Gegenstand, der alle Elemente umfasst. Der service hat mehrere Arten basiert auf Einem, aber mit Einschränkungen, so dass die vererbten Typen sind in der Regel kleiner als der Basis-Typ - hier am Beispiel des Typ B.

In der schema-Viewer, wie der in Visual Studio 2010, SoapUI, etc.. das sieht aus wie erwartet. Eine hat 2 Elemente und B nur 1 (= element 2).

Mithilfe svcutil ich bekomme den vollen Satz von Elementen, die in meinen beiden Typen A & B, oder beim spielen mit den Optionen bekomme ich Fehlermeldungen wie:

Fehler: Typ 'B' in namespace 'http://tempuri.org/XMLSchema.xsd' kann nicht importiert werden. Komplexe Typen abgeleitet durch Einschränkung
nicht unterstützt. Entweder ändern Sie das schema so, dass die Typen zuordnen können Daten Vertragstypen oder verwenden ImportXmlType oder verwenden Sie eine
unterschiedliche serializer.

Ausblenden von Feldern/Eigenschaften geerbt Typen ist nicht eine Praxis/Straße ich Reise gerne, aber wenn ich nicht den provider ändern Sie die WSDL-es scheint, ich habe es so zu tun.

Gibt es alternativen zu svcutil, die handhaben das korrekt, oder muss ich hand-code-meine Proxys?


Update 1

Wie bereits von John Saunders habe ich nicht dargestellt, die Ergebnisse der Vorschläge aus svcutil. Das war teilweise zu halten, den kurzen post... aber hier geht:

svcutil-schema.xsd /importXmlTypes /datacontractonly Ergebnisse in:

[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;
    }
}

Arbeiten auf Xml-Ebene ist nicht erwünscht und würde uns zwingen, Sie zu schreiben, ein wrapper. Es ist einfacher, handcode der proxy von Beginn an entgegen zu wirken.

svcutil-schema.xsd /serializer:XmlSerializer /datacontractonly Gibt den folgenden Fehler und die Ursache dafür Frage ich ja nach alternativen Werkzeugen.

svcutil-schema.xsd /serializer:XmlSerializer /datacontractonly
Fehler: Typ 'B' in namespace 'http://tempuri.org/XMLSchema.xsd" nicht
importiert werden können. Komplexe Typen abgeleitet durch Einschränkung nicht unterstützt.
Entweder ändern Sie das schema so, dass die Typen zuordnen können Daten Vertrag
Typen oder verwenden ImportXmlType oder verwenden Sie eine andere serializer.

Wenn Sie mit der /dataContractOnly option zum importieren von Daten Vertrag
Typen, die immer diese Fehlermeldung, prüfen, unter Verwendung xsd.exe
statt. Typen generiert xsd.exe verwendet werden kann in der Windows
Communication Foundation nach dem auftragen der
XmlSerializerFormatAttribute Attribut auf Ihrem service-Vertrag.
Alternativ könnten Sie mit der /importXmlTypes option zum importieren
diese Typen als XML-Typen zu verwenden, mit DataContractFormatAttribute
Attribut auf Ihrem service-Vertrag.

Mit xsd-schema.xsd /c gibt einen Typ B, der erbt Ein ohne sich zu verstecken, element1:

[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;
        }
    }
}
  • Welchen Teil der Fehlermeldung hast du nicht verstanden? Er erzählte Ihnen genau, wie das problem zu lösen.
  • Nein, es gibt mir nicht das erwartete Ergebnis (beachten Sie auch, sagte ich Meldungen wie - es war nur ein Beispiel - eine schlechte, ich weiß...). Wenn Sie versucht haben, mit diesen Optionen werden Sie sehen, dass es nicht generieren einer proxy mit den entsprechenden Eigenschaften. Das Ergebnis ist, dass ich am Ende mit mit mit Listen von Elementen und serializtion direkt.
  • Ich habe kein Interesse daran, Sie versuchen, die Optionen. Sie haben versucht, Sie, und Sie wissen, die Ergebnisse. Bitte show Sie uns, was Sie versucht, und show uns die Ergebnisse.
Schreibe einen Kommentar