2010-02-03 16 views
26

Chcę móc wygenerować DataContract z pliku XSD, najlepiej przy użyciu xsd.exe tool. Jaki jest najłatwiejszy sposób automatycznego wygenerowania [DataContract] i [DataMember] na każdym z moich produktów?Generowanie DataContract z XSD

Czy istnieje lepsze podejście? Próbuję uniknąć konieczności odtworzenia umowy danych za każdym razem, gdy plik XSD zostanie zmieniony i zregenerowany.

+0

Ok teraz jestem coraz kolejny błąd. maxOccurs na DownloadRequestItem musi być 1 To jest mój schemat \t elementFormDefault = "kwalifikowany"> \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

Czy możesz zaktualizować oryginalne pytanie, edytując je? Umieszczenie XML w komentarzach jest NAPRAWDĘ NAPRAWDĘ trudne do odczytania i bałagan ..... –

+0

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

Odpowiedz

42

Narzędziepoprzedza WCF i nie wie nic na temat [DataContract] i [DataMember]. Jeśli używasz xsd.exe, będziesz musiał zmienić WCF, aby użyć XmlSerializer zamiast domyślnego DataContractSerializer do serializacji umów danych.

Ekwiwalent WCF dla xsd.exe to svcutil.exe - ma parametr /dconly, który tworzy tylko umowy danych z danego pliku XSD. Spowoduje to wygenerowanie dla Ciebie pliku C# lub VB.NET, zawierającego dobrze zapisane adnotacje danych.

Zastosowanie:

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

To wygeneruje plik * .cs o tej samej nazwie bazowej w swoim katalogu.

Z mojego doświadczenia wynika, że ​​svcutil.exe jest dość wrażliwy na jego struktury XML - więc nie zdziw się, jeśli szczeka na ciebie z tonami ostrzeżeń i/lub błędów.

+0

Dziękuję Nie wiedziałem, że to narzędzie istnieje – Daveo

+0

* dość wybredny o swoich strukturach XML * - to, co DCS robi i nie obsługuje, jest tutaj udokumentowane https://msdn.microsoft.com/en-us/library/ms733112 (v = vs.110) .aspx –

11

Użyj svcutil.exe zamiast xsd.exe

Jak korzystać? Przejdź do menu Start -> Microsoft Visual Studio 2008 -> Narzędzia Visual Studio -> Wiersz polecenia programu Visual Studio 2008

i Zmień żądany katalog lub zmień katalog na taki, w którym znajduje się twój xsd.

svcutil.exe /help 

wyświetli listę wszystkich opcji.

jedną z opcji używam do generowania danych contarct tylko

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

Przechowywać kodowania Hava dobry dzień!

3

DataContracts od XSD first!

Jest to nowoczesny sposób i bardzo dobra praktyka, jednak VS2010 ma bardzo ograniczone wsparcie automatyzacji za to. Dlatego usiadłem i napisałem czysty cel msbuild, który: nie wymaga modyfikacji pliku proj i generuje .g.cs. Możesz także łatwo uzyskać kod VB przy pomocy drobnych poprawek w tym pliku.

Instalacja: Skopiuj kod i zapisz go jako plik GenerateDataContractsFromXSD.targets do folderu "C: \ Program Files \ MSBuild \ 4.0 \ Microsoft.Common.targets \ ImportAfter". To sprawia, że ​​msbuild odczytuje go przy każdym uruchomieniu i to samo dotyczy VS2010.

Zastosowanie:

  • ReStart VS2010 i dodać XSD do projektu.
  • Wybierz plik XSD i naciśnij klawisz F4, aby wyświetlić okno narzędzia właściwości.
  • Zmień właściwość działania konstrukcyjnego, aby zawierała wartość GenerateDataContracts
  • Utwórz projekt za pomocą pliku XSD. Generuje pierwszy plik .g.cs.
  • Obejmij widok w eksploratorze rozwiązań, aby wyświetlić wszystkie pliki w systemie plików.
  • Dołącz nowy wygenerowany plik do projektu.
  • Dodaj odniesienie do zestawu System.Runtime.Serialization.

Ciesz się.

<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

Twoje rozwiązanie jest intrygujące, ale "C: \ Program Files \ MSBuild \ 4.0 \ Microsoft.Common.targets \ ImportAfter" Nie widzę tego folderu na moim komputerze. – Serge

+1

@Serge, ** Założenia ** są takie, że używasz MSBuild z .NET4 i VS2010, w tym przypadku po prostu utwórz brakujące foldery i zapisz plik celów tam (msbuild internaly przeszukuje tę lokalizację). To rozwiązanie może również działać z poprzednią wersją MSBuild, jeśli zostały wprowadzone odpowiednie zmiany. – pavelz

1

Na komputerze 64-bitowym można go znaleźć w

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

W tym przypadku:

%systemdrive%\Program Files (x86)\MSBuild\4.0\Microsoft.Common.Targets\ImportAfter\ 
Powiązane problemy