27

我希望能够DataContract从 XSD 文件生成一个,最好使用xsd.exe 工具。它在我的每个项目上自动生成[DataContract]and的最简单方法是什么?[DataMember]

还是有更好的方法?我试图避免每次更改和重新生成 XSD 文件时都必须重新创建数据合同。

4

4 回答 4

45

xsd.exe工具早于 WCF 并且不知道任何关于[DataContract][DataMember]. 如果确实使用xsd.exe,则必须将 WCF 切换为使用XmlSerializer代替其默认值DataContractSerializer来序列化数据协定。

WCF 的等价物xsd.exesvcutil.exe- 它有一个参数/dconly,它只从给定的 XSD 文件创建数据协定。这将为您生成一个 C# 或 VB.NET 文件,其中包含经过良好注释的数据协定。

用法:

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

这将在您的目录中生成一个具有相同基本名称的 *.cs 文件。

根据我的经验,svcutil.exe它对它的 XML 结构非常挑剔——所以如果它向你发出大量警告和/或错误,请不要感到惊讶。

于 2010-02-03T06:07:33.710 回答
12

使用 svcutil.exe 而不是 xsd.exe

如何使用 ?转到开始菜单 --> Microsoft Visual Studio 2008 --> Visual Studio 工具 --> Visual Studio 2008 命令提示符

并更改您想要的目录或将目录更改为您的 xsd 在那里。

svcutil.exe /help 

它将列出所有选项。

我用来生成数据合同的选项之一是

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

继续编码,祝你有美好的一天!

于 2010-11-29T22:03:33.213 回答
3

首先来自 XSD 的 DataContracts!

这是现代方式和非常好的实践,但是,VS2010 对它的自动化支持非常有限。因此,我坐下来编写了一个纯 msbuild 目标:不需要修改 proj 文件并生成 .g.cs。您还可以通过在此文件中进行一些小调整来非常轻松地生成 VB 代码。

安装:复制代码并将其作为 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>
于 2012-03-08T15:10:37.867 回答
1

在 64 位机器上,您会在

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

在这种情况下:

%systemdrive%\Program Files (x86)\MSBuild\4.0\Microsoft.Common.Targets\ImportAfter\
于 2014-09-15T10:09:14.253 回答