2010-02-03 145 views
26

我希望能夠從XSD文件生成DataContract,最好使用xsd.exe tool。在我的每件商品上自動生成[DataContract][DataMember]的最簡單方法是什麼?從XSD生成DataContract

還是有更好的方法?我試圖避免每次更改和重新生成XSD文件時都必須重新創建數據協定。

+0

好吧,我現在得到另一個錯誤。上DownloadRequestItem maxOccurs的必須是1 這是我的架構 \t將elementFormDefault = 「合格」> \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

你能否通過編輯更新你的原始問題?把XML寫入註釋是真的很難閱讀和一個爛攤子..... –

+0

wcfBlue http://wscfblue.codeplex。com/ – 2010-10-19 15:04:12

回答

42

xsd.exe工具早於WCF,並且不知道關於[DataContract][DataMember]的任何內容。如果確實使用xsd.exe,則必須將WCF切換爲使用XmlSerializer而不是其默認DataContractSerializer來序列化數據協定。

xsd.exe的WCF等效爲svcutil.exe - 它具有參數/dconly,該參數僅從給定的XSD文件創建數據契約。這將爲您生成一個C#或VB.NET文件,其中包含很好註釋的數據合同。

用法:

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

這將產生在目錄中的相同的基本名稱* cs文件。

根據我的經驗,svcutil.exe對於它的XML結構非常挑剔 - 所以如果它以大量的警告和/或錯誤咆哮着你,不要感到驚訝。

+0

謝謝我不知道這個工具存在 – Daveo

+0

*對它的XML結構相當挑剔* - 什麼DCS做和不支持在這裏記錄https://msdn.microsoft.com/en-us/library/ms733112( v = vs.110).aspx –

11

使用svcutil.exe而不是xsd.exe

如何使用? 轉到開始菜單 - > Microsoft Visual Studio 2008 - > Visual Studio工具 - > Visual Studio 2008命令提示符

並更改您想要的directoy或將目錄更改爲您的xsd在那裏。

svcutil.exe /help 

它將列出所有選項。

我用它來生成數據contarct選項之一不僅是

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

保持編碼HAVA美好的一天!

3

來自XSD的DataContracts首先!

這是現代的方式和非常好的做法,然而,VS2010有非常有限的自動化支持 它。因此,我坐下來寫了一個純粹的msbuild目標,其中:不需要proj文件修改 並生成.g.cs。您也可以通過在該文件中進行小小的調整來輕鬆實現生成VB代碼。

Instalaltion:將代碼複製並保存爲GenerateDataContractsFromXSD.targets文件到文件夾'C:\ Program Files \ MSBuild \ 4.0 \ Microsoft.Common.targets \ ImportAfter'中。這使得msbuild每次啓動時都會讀取它,同樣適用於VS2010。

用法:

  • 重新啓動VS2010並添加XSD到您的項目。
  • 選擇XSD文件並按F4以顯示屬性工具窗口。
  • 將Build Action屬性更改爲包含值GenerateDataContracts
  • 使用XSD文件構建項目。它生成第一個.g.cs文件。
  • 在解決方案資源管理器中顯示視圖以顯示文件系統上的所有文件。
  • 將新生成的文件包含在項目中。
  • 添加對System.Runtime.Serialization程序集的引用。

享受。

<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

您的解決方案是Interresting,但「C:\ Program Files \ MSBuild \ 4.0 \ Microsoft.Common.targets \ ImportAfter」我沒有在我的電腦上看到該文件夾​​。 – Serge

+1

@Serge,**假設**是你使用.NET4和VS2010的MSBuild,在這種情況下只需創建丟失的文件夾並在那裏保存目標文件(msbuild內部搜索此位置)。如果提供了適當的更改,此解決方案也可以與之前的MSBuild版本一起使用。 – pavelz

1

在64位機器,你會發現它在

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

在這種情況下:

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