Vertrag zuerst-Tool

Dienstverträge müssen häufig aus vorhandenen Diensten erstellt werden. In .NET Framework 4.5 und höher können Datenvertragsklassen mithilfe des Contract-First-Tools automatisch aus vorhandenen Diensten erstellt werden. Zum Verwenden des Vertrag zuerst-Tools muss die XSD (XML Schema Definition)-Datei lokal heruntergeladen werden. Das Tool kann keine Remotedatenverträge per HTTP importieren.

Das Contract-First-Tool ist als Buildaufgabe in Visual Studio 2012 integriert. Die von der Buildaufgabe generierten Codedateien werden bei jeder Projekterstellung erzeugt, sodass das Projekt einfach Änderungen im zugrunde liegenden Dienstvertrag übernehmen kann.

Folgende Schematypen können vom Vertrag zuerst-Tool importiert werden:

<xsd:complexType>
 <xsd:simpleType>
 </xsd:simpleType>
</xsd:complexType>

Einfache Typen werden nicht generiert, wenn es sich um primitive Typen, z. B. Int16 oder String, handelt. Komplexe Typen werden nicht generiert, wenn sie vom Typ Collection sind. Typen werden ebenfalls nicht generiert, wenn sie Teil eines anderen xsd:complexType sind. In allen diesen Fällen werden stattdessen Verweise dieser Typen auf im Projekt vorhandene Typen verwendet.

Hinzufügen eines Datenvertrags zu einem Projekt

Bevor das Vertrag zuerst-Tool verwendet werden kann, muss dem Projekt der Dienstvertrag (XSD) hinzugefügt werden. In dieser Übersicht wird zum Veranschaulichen von Vertrag zuerst-Funktionen der folgende Vertrag verwendet. Diese Dienstdefinition ist nur ein kleiner Teil des Dienstvertrags, der von der Such-API von Bing verwendet wird.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="ServiceSchema"
    targetNamespace="http://tempuri.org/ServiceSchema.xsd"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/ServiceSchema.xsd"
    xmlns:mstns="http://tempuri.org/ServiceSchema.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
  <xs:complexType name="SearchRequest">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" name="Version" type="xs:string" default="2.2" />
      <xs:element minOccurs="0" maxOccurs="1" name="Market" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="1" name="UILanguage" type="xs:string" />
      <xs:element minOccurs="1" maxOccurs="1" name="Query" type="xs:string" />
      <xs:element minOccurs="1" maxOccurs="1" name="AppId" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="1" name="Latitude" type="xs:double" />
      <xs:element minOccurs="0" maxOccurs="1" name="Longitude" type="xs:double" />
      <xs:element minOccurs="0" maxOccurs="1" name="Radius" type="xs:double" />
    </xs:sequence>
  </xs:complexType>
  <xs:simpleType name="WebSearchOption">
    <xs:restriction base="xs:string">
      <xs:enumeration value="DisableHostCollapsing" />
      <xs:enumeration value="DisableQueryAlterations" />
    </xs:restriction>
  </xs:simpleType>
</xs:schema>

Um dem Projekt den obigen Dienstvertrag hinzufügen, klicken Sie mit der rechten Maustaste auf das Projekt, und wählen Sie Neu hinzufügen aus. Wählen Sie im WCF-Bereich des Dialogfelds Vorlagen die Schemadefinition aus, und benennen Sie die neue Datei mit SampleContract.xsd. Kopieren Sie den obigen Code, und fügen Sie ihn in die Codeansicht der neuen Datei ein.

Konfigurieren von Vertrag zuerst-Optionen

Contract-First-Optionen können im Eigenschaftenmenü eines WCF-Projekts konfiguriert werden. Zur Nutzung der Contract-First-Entwicklung aktivieren Sie auf der WCF-Seite des Projekteigenschaftenfensters das Kontrollkästchen XSD als Typdefinitionssprache aktivieren.

Screenshot of the WCF Options with contract-first development enabled.

Um erweiterte Eigenschaften zu konfigurieren, klicken Sie auf die Schaltfläche Erweitert.

Advanced Contract Code Generation Settings dialog box.

Die folgenden erweiterten Einstellungen können für die Codegenerierung aus Verträgen konfiguriert werden. Die Einstellungen können nur für alle Dateien im Projekt konfiguriert werden. Das Konfigurieren der Einstellungen für einzelne Dateien ist derzeit nicht möglich.

  • Serialisierungsmodus: Diese Einstellung bestimmt, welches Serialisierungsmodul für das Lesen von Dienstvertragsdateien verwendet wird. Wenn XML-Serialisierungsmodul ausgewählt ist, sind die Optionen Sammlungstypen und Typen wiederverwenden deaktiviert. Diese Optionen gelten nur für den Datenvertragsserialisierer.

  • Typen wiederverwenden: Diese Einstellung gibt an, welche Bibliotheken für die Wiederverwendung von Typen verwendet werden. Die Einstellung ist nur gültig, wenn Serialisierungsmodus auf Datenvertragsserialisierer festgelegt ist.

  • Sammlungstyp: Diese Einstellung gibt den vollqualifizierten oder durch die Assembly qualifizierten Typ an, der für den Sammlungsdatentyp verwendet werden soll. Die Einstellung ist nur gültig, wenn Serialisierungsmodus auf Datenvertragsserialisierer festgelegt ist.

  • Wörterbuchtyp: Diese Einstellung gibt den vollqualifizierten oder durch die Assembly qualifizierten Typ an, der für den Wörterbuchdatentyp verwendet werden soll.

  • EnableDataBinding: Diese Einstellung gibt an, ob die INotifyPropertyChanged-Schnittstelle für alle Datentypen implementiert werden soll, um die Datenbindung zu implementieren.

  • ExcludedTypes: Diese Einstellung gibt die Liste der vollqualifizierten oder durch die Assembly qualifizierten Typen an, die aus den Assemblys, auf die verwiesen wird, ausgeschlossen werden sollen. Die Einstellung ist nur gültig, wenn Serialisierungsmodus auf Datenvertragsserialisierer festgelegt ist.

  • GenerateInternalTypes: Diese Einstellung gibt an, ob Klassen generiert werden, die als intern markiert sind. Die Einstellung ist nur gültig, wenn Serialisierungsmodus auf Datenvertragsserialisierer festgelegt ist.

  • GenerateSerializableTypes: Diese Einstellung gibt an, ob Klassen mit dem SerializableAttribute-Attribut generiert werden sollen. Die Einstellung ist nur gültig, wenn Serialisierungsmodus auf Datenvertragsserialisierer festgelegt ist.

  • ImportXMLTypes: Diese Einstellung gibt an, ob der Datenvertragsserialisierer so konfiguriert wird, dass das SerializableAttribute-Attribut auf Klassen ohne das DataContractAttribute-Attribut angewendet wird. Die Einstellung ist nur gültig, wenn Serialisierungsmodus auf Datenvertragsserialisierer festgelegt ist.

  • SupportFx35TypedDataSets: Diese Einstellung gibt an, ob zusätzliche Funktionen für typisierte Datasets bereitgestellt werden, die für .NET Framework 3.5 erstellt wurden. Wenn dieser Wert „TRUE“ ist und Serialisierungsmodus auf XML-Serialisierer festgelegt ist, wird dem XML-Schema-Importprogramm die TypedDataSetSchemaImporterExtensionFx35-Erweiterung hinzugefügt. Wenn dieser Wert „FALSE“ ist und Serialisierungsmodus auf Datenvertragsserialisierer festgelegt ist, wird der Typ DateTimeOffset aus Verweisen ausgeschlossen, sodass für ältere Frameworkversionen immer DateTimeOffset generiert wird.

  • InputXsdFiles: Diese Einstellung gibt die Liste der Eingabedateien an. Jede Datei muss ein gültiges XML-Schema enthalten.

  • Sprache: Diese Einstellung gibt die Sprache des generierten Vertragscodes an. Die Einstellung muss vom CodeDomProvider erkannt werden können.

  • NamespaceMappings: Diese Einstellung gibt die Zuordnungen zwischen XSD-Zielnamespaces und CLR-Namespaces an. Jede Zuordnung sollte folgendes Format aufweisen:

    "Schema Namespace, CLR Namespace"
    

    Die XML-Serialisierung akzeptiert nur eine Zuordnung im folgenden Format:

    "*, CLR Namespace"
    
  • OutputDirectory: Diese Einstellung gibt das Verzeichnis an, in dem die Codedateien generiert werden.

Die Einstellungen werden verwendet, um Dienstvertragstypen aus Vertragsdateien zu generieren, wenn das Projekt erstellt wird.

Verwenden der Vertrag zuerst-Entwicklung

Nachdem Sie dem Projekt den Dienstvertrag hinzugefügt und die Buildeinstellungen bestätigt haben, erstellen Sie das Projekt, indem Sie F6 drücken. Die Typen, die im Dienstvertrag definiert sind, stehen dann für die Verwendung im Projekt bereit.

Um die im Dienstvertrag definierten Typen zu verwenden, fügen Sie unter dem aktuellen Namespace einen Verweis auf ContractTypes hinzu:

using MyProjectNamespace.ContractTypes;

Die im Dienstvertrag definierten Typen lassen sich dann wie unten dargestellt im Projekt auflösen:

SearchRequest class showing in IntelliSense after typing the first few letters.

Die vom Tool generierten Typen werden in der Datei GeneratedXSDTypes.cs erstellt. Die Datei wird standardmäßig im Verzeichnis <Projektverzeichnis>/obj/<Buildkonfiguration>/XSDGeneratedCode/ erstellt. Das Beispielschema am Anfang dieses Artikels wird wie folgt konvertiert:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.17330
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace TestXSD3.ContractTypes
{
    using System.Xml.Serialization;

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.17330")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/ServiceSchema.xsd")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace="http://tempuri.org/ServiceSchema.xsd", IsNullable=true)]
    public partial class SearchRequest
    {

        private string versionField;

        private string marketField;

        private string uILanguageField;

        private string queryField;

        private string appIdField;

        private double latitudeField;

        private bool latitudeFieldSpecified;

        private double longitudeField;

        private bool longitudeFieldSpecified;

        private double radiusField;

        private bool radiusFieldSpecified;

        public SearchRequest()
        {
            this.versionField = "2.2";
        }

        /// <remarks/>
        [System.ComponentModel.DefaultValueAttribute("2.2")]
        public string Version
        {
            get
            {
                return this.versionField;
            }
            set
            {
                this.versionField = value;
            }
        }

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

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

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

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

        /// <remarks/>
        public double Latitude
        {
            get
            {
                return this.latitudeField;
            }
            set
            {
                this.latitudeField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public bool LatitudeSpecified
        {
            get
            {
                return this.latitudeFieldSpecified;
            }
            set
            {
                this.latitudeFieldSpecified = value;
            }
        }

        /// <remarks/>
        public double Longitude
        {
            get
            {
                return this.longitudeField;
            }
            set
            {
                this.longitudeField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public bool LongitudeSpecified
        {
            get
            {
                return this.longitudeFieldSpecified;
            }
            set
            {
                this.longitudeFieldSpecified = value;
            }
        }

        /// <remarks/>
        public double Radius
        {
            get
            {
                return this.radiusField;
            }
            set
            {
                this.radiusField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public bool RadiusSpecified
        {
            get
            {
                return this.radiusFieldSpecified;
            }
            set
            {
                this.radiusFieldSpecified = value;
            }
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.17330")]
    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/ServiceSchema.xsd")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace="http://tempuri.org/ServiceSchema.xsd", IsNullable=false)]
    public enum WebSearchOption
    {

        /// <remarks/>
        DisableHostCollapsing,

        /// <remarks/>
        DisableQueryAlterations,
    }
}

Fehler und Warnungen

Fehler und Warnungen, die bei der Analyse des XSD-Schemas auftreten, werden als Buildfehler und Warnungen angezeigt.

Schnittstellenvererbung

Bei der Vertrag zuerst-Entwicklung kann keine Schnittstellenvererbung verwendet werden. Dies entspricht dem Verhalten von Schnittstellen in anderen Vorgängen. Verwenden Sie für eine Schnittstelle, die eine Basisschnittstelle erbt, zwei verschiedene Endpunkte. Der erste Endpunkt verwendet den geerbten Vertrag, und der zweite Endpunkt implementiert die Basisschnittstelle.