从 XSD 生成 DataContract
Posted
技术标签:
【中文标题】从 XSD 生成 DataContract【英文标题】:Generate DataContract from XSD 【发布时间】:2011-01-12 10:24:04 【问题描述】:我希望能够从 XSD 文件生成DataContract
,最好使用xsd.exe tool。在我的每个项目上自动生成 [DataContract]
和 [DataMember]
的最简单方法是什么?
或者有更好的方法吗?我试图避免每次更改和重新生成 XSD 文件时都必须重新创建数据协定。
【问题讨论】:
好的,我现在遇到另一个错误。 DownloadRequestItem 上的 maxOccurs 必须为 1 这是我的架构 elementFormDefault="qualified">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 结构非常挑剔 - 因此,如果它向您发出大量警告和/或错误,请不要感到惊讶。
【讨论】:
谢谢 不知道有这个工具 对它的 XML 结构非常挑剔 - DCS 支持和不支持的内容记录在这里 msdn.microsoft.com/en-us/library/ms733112(v=vs.110).aspx【参考方案2】:使用 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
继续编码,祝你有美好的一天!
【讨论】:
【参考方案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 "$(DataContractGeneratedFilePath)"" />
<Exec
Condition="'@(DataContractItems)' != ''"
Outputs="$(DataContractGeneratedFilePath)"
Command=""$(WIN_SDK_PATH)bin\SvcUtil.exe" @(SvcUtilParam, ' ') @(GenerateDataContracts -> '%(DataContractSchemaMapping)') "/out:$(DataContractGeneratedFilePath)" "%(DataContractItems.FullPath)"" />
</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>
【讨论】:
你的解决方案很有趣,但是“C:\Program Files\MSBuild\4.0\Microsoft.Common.targets\ImportAfter”我没有在我的电脑上看到那个文件夹。 @Serge,假设是您使用 .NET4 和 VS2010 的 MSBuild,在这种情况下,只需创建缺少的文件夹并将目标文件保存在那里(msbuild internaly搜索此位置)。如果提供了适当的更改,此解决方案也可能适用于以前的 MSBuild 版本。【参考方案4】:在 64 位机器上,您会在
中找到它%systemdrive%\Program Files (x86)\MSBuild\<version you use>
在这种情况下:
%systemdrive%\Program Files (x86)\MSBuild\4.0\Microsoft.Common.Targets\ImportAfter\
【讨论】:
以上是关于从 XSD 生成 DataContract的主要内容,如果未能解决你的问题,请参考以下文章