2010-02-03 13 views
26

Ich möchte in der Lage sein, eine DataContract aus einer XSD-Datei zu generieren, vorzugsweise mit der xsd.exe tool. Was ist der einfachste Weg, um automatisch die [DataContract] und [DataMember] auf jedem meiner Artikel zu generieren?DataContract von XSD generieren

Oder gibt es einen besseren Ansatz? Ich versuche zu vermeiden, den Datenvertrag jedes Mal neu erstellen zu müssen, wenn die XSD-Datei geändert und neu generiert wird.

+0

Ok ich jetzt einen anderen Fehler. maxOccurs auf DownloadRequestItem muss 1 sein Das ist mein Schema \t ElementFormDefault- = "qualified"> \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t – Daveo

+0

können Sie bitte Ihre ursprüngliche Frage aktualisieren, indem Sie es bearbeiten? XML in Kommentare einfügen ist wirklich wirklich schwer zu lesen und ein Durcheinander ..... –

+0

wcfBlue http: //wscfblue.codeplex.com/ –

Antwort

42

Das Tool xsd.exe ist älter als WCF und weiß nichts über [DataContract] und [DataMember]. Wenn Sie xsd.exe verwenden, müssen Sie WCF für die Verwendung der XmlSerializer statt seiner Standard DataContractSerializer für die Serialisierung der Datenverträge wechseln.

Das WCF-Äquivalent für xsd.exe ist svcutil.exe - es hat einen Parameter /dconly, der nur die Datenverträge aus einer bestimmten XSD-Datei erstellt. Dadurch wird eine C# - oder VB.NET-Datei für Sie generiert, die die annotierten Datenverträge enthält.

Verbrauch:

svcutil.exe (name of your XSD).xsd /dconly 

Dies würde eine * CS-Datei mit dem gleichen Basisnamen in Ihrem Verzeichnis generiert.

Nach meiner Erfahrung ist svcutil.exe ziemlich wählerisch über seine XML-Strukturen - seien Sie also nicht überrascht, wenn es Sie mit Tonnen von Warnungen und/oder Fehlern bellt.

+0

Vielen Dank Ich wusste nicht, dieses Tool existierte – Daveo

+0

* ziemlich wählerisch über seine XML-Strukturen * - was DCS tut und nicht unterstützt, ist hier dokumentiert https://msdn.microsoft.com/en-us/library/ms733112 (v = vs.110) .aspx –

11

Verwenden svcutil.exe statt xsd.exe

So verwenden? Gehen Sie zu Startmenü -> Microsoft Visual Studio 2008 -> Visual Studio Tools -> Visual Studio 2008 Eingabeaufforderung

und ändern Sie die gewünschte Verzeichnis oder ändern Sie das Verzeichnis, in dem Ihre xsd ist.

svcutil.exe /help 

wird es alle Optionen auflisten.

eine der Option I verwenden, um Daten nur dann erzeugen contarct ist

svcutil.exe /target:code /n:*,[Your Company and Department].Common.DataTransferObjects /dataContractOnly /serializer:auto /importXmlTypes common.xsd /out:common.cs 

Halten hava guter Tag Codierung!

3

DataContracts von XSD zuerst!

Es ist die moderne Art und sehr gute Praxis, jedoch hat VS2010 sehr begrenzte Automatisierungsunterstützung dafür. Daher habe ich mich hingesetzt und ein reines msbuild target geschrieben, das: keine proj Dateiänderungen benötigt und generiert .g.cs. Sie können auch leicht VB-Code mit kleinen Verbesserungen in dieser Datei erzeugen.

Instalaktion: Kopieren Sie den Code und speichern Sie ihn als GenerateDataContractsFromXSD.targets-Datei in den Ordner 'C: \ Programme \ MSBuild \ 4.0 \ Microsoft.Common.targets \ ImportAfter'. Dies macht msbuild es jedes Mal zu lesen, und es gilt auch für VS2010.

Verbrauch:

  • ReStart VS2010 und ein XSD in Ihrem Projekt hinzufügen.
  • Wählen Sie die XSD-Datei und drücken Sie F4, um das Werkzeugfenster Eigenschaften anzuzeigen.
  • Ändern Sie die Buildaktionseigenschaft so, dass sie den Wert enthält GenerateDataContracts
  • Erstellen Sie das Projekt mit der XSD-Datei. Es generiert die erste .g.cs-Datei.
  • Ändern Sie die Ansicht im Projektmappen-Explorer, um alle Dateien im Dateisystem anzuzeigen.
  • Fügen Sie die neu generierte Datei in das Projekt ein.
  • Fügen Sie einen Verweis auf die System.Runtime.Serialization-Assembly hinzu.

Genießen.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <!-- Inject into the sequence of targets in order to add a generated file to compile --> 
    <PropertyGroup> 
    <CoreCompileDependsOn> 
     GenerateDataContractsFromXSD; 
     $(CoreCompileDependsOn); 
    </CoreCompileDependsOn> 
    </PropertyGroup> 

    <ItemGroup> 
    <SvcUtilParam Include="/nologo" /> 
    <SvcUtilParam Include="/target:code" /> 
    <SvcUtilParam Include="/dataContractOnly" /> 
    <SvcUtilParam Include="/serializer:DataContractSerializer" /> 
    <SvcUtilParam Include="/language:csharp" /> 
    <SvcUtilParam Include="/enableDataBinding" /> 
    <SvcUtilParam Include="/serializable" /> 
    <SvcUtilParam Include="/internal" /> 
    </ItemGroup> 

    <ItemGroup> 
    <AvailableItemName Include="GenerateDataContracts"> 
     <Targets>GenerateDataContractsFromXSD</Targets> 
    </AvailableItemName> 
    </ItemGroup> 

    <ItemDefinitionGroup> 
    <GenerateDataContracts> 
     <!-- Use the following options to pass serialization options to SVCUTIL --> 
     <DataContractSchemaMapping>"/n:*,$(AssemblyName).Data"</DataContractSchemaMapping> 
    </GenerateDataContracts> 
    </ItemDefinitionGroup> 

    <!-- Automated Data Contract Serialisation using the SvcUtil.Exe tool --> 
    <!-- in order to make it automated you have to set the build tool in properties window to GenerateDataContracts --> 
    <Target Name="GenerateDataContractsFromXSD" 
      Inputs="@(GenerateDataContracts)" 
      Outputs="%(GenerateDataContracts.RootDir)\%(GenerateDataContracts.Directory)%(GenerateDataContracts.Filename).g.cs"> 

    <ItemGroup> 
     <DataContractItems Include="@(GenerateDataContracts -> '%(FullPath)')" Condition="'%(Extension)' == '.xsd'" /> 
    </ItemGroup> 

    <PropertyGroup> 
     <DataContractGeneratedFilePath>%(DataContractItems.RootDir)\%(DataContractItems.Directory)%(DataContractItems.Filename).g.cs</DataContractGeneratedFilePath> 
     <DataContractGeneratedIdentifier>@(GenerateDataContracts -> '%(RelativeDir)')%(DataContractItems.Filename).g.cs</DataContractGeneratedIdentifier> 
    </PropertyGroup> 

    <GetFrameworkSdkPath> 
     <Output TaskParameter="Path" PropertyName="WIN_SDK_PATH" /> 
    </GetFrameworkSdkPath> 

    <Exec 
     Condition="'@(DataContractItems)' != ''" 
     Command="attrib -r &quot;$(DataContractGeneratedFilePath)&quot;" /> 

    <Exec 
     Condition="'@(DataContractItems)' != ''" 
     Outputs="$(DataContractGeneratedFilePath)" 
     Command="&quot;$(WIN_SDK_PATH)bin\SvcUtil.exe&quot; @(SvcUtilParam, ' ') @(GenerateDataContracts -> '%(DataContractSchemaMapping)') &quot;/out:$(DataContractGeneratedFilePath)&quot; &quot;%(DataContractItems.FullPath)&quot;" /> 

    </Target> 

    <Target Name="GetCopyGenerateDataContractItems" 
      AfterTargets="AssignTargetPaths"> 
    <ItemGroup> 
     <DataContractItems Include="@(GenerateDataContracts -> '%(FullPath)')" Condition="'%(Extension)' == '.xsd'" /> 
    </ItemGroup> 

    <AssignTargetPath Files="@(DataContractItems)" RootFolder="$(MSBuildProjectDirectory)"> 
     <Output TaskParameter="AssignedFiles" ItemName="ContentWithTargetPath" /> 
    </AssignTargetPath> 

    </Target> 

</Project> 
+0

Ihre Lösung ist interessant, aber "C: \ Programme \ MSBuild \ 4.0 \ Microsoft.Common.targets \ ImportAfter" Ich sehe diesen Ordner nicht auf meinem Computer. – Serge

+1

@Serge, ** Annahmen ** sind, dass Sie MSBuild von .NET4 und VS2010 verwenden, in diesem Fall einfach die fehlenden Ordner erstellen und die Zieldatei dort speichern (intern sucht msbuild diesen Ort). Diese Lösung funktioniert möglicherweise auch mit der vorherigen MSBuild-Version, wenn entsprechende Änderungen bereitgestellt wurden. – pavelz

1

Auf einem 64-Bit-Rechner finden Sie es in

%systemdrive%\Program Files (x86)\MSBuild\<version you use> 

In diesem Fall:

%systemdrive%\Program Files (x86)\MSBuild\4.0\Microsoft.Common.Targets\ImportAfter\ 
Verwandte Themen