.net - serializar - Generar DataContract desde XSD
serialize and deserialize c# (4)
Quiero poder generar un DataContract
desde un archivo XSD, preferiblemente usando la herramienta xsd.exe . ¿Cuál es la forma más fácil de generar automáticamente [DataContract]
y [DataMember]
en cada uno de mis artículos?
¿O hay un mejor enfoque? Estoy tratando de evitar tener que volver a crear el contrato de datos cada vez que se cambia y se regenera el archivo XSD.
¡DataContracts de XSD primero!
Es la forma moderna y muy buena práctica, sin embargo, VS2010 tiene un soporte de automatización muy limitado. Por lo tanto, me senté y escribí un objetivo de msbuild puro que: no requiere modificaciones del archivo proj y genera .g.cs. También puede lograr generar código VB muy fácilmente con pequeños ajustes en este archivo.
Instalación: copie el código y guárdelo como archivo GenerateDataContractsFromXSD.targets en la carpeta ''C: / Program Files / MSBuild / 4.0 / Microsoft.Common.targets / ImportAfter''. Esto hace que msbuild lo lea cada vez que se inicia y lo mismo aplica para VS2010.
Uso:
- Reinicie VS2010 y agregue un xsd a su proyecto.
- Seleccione el archivo XSD y presione F4 para mostrar la ventana de herramientas de propiedades.
- Cambie la propiedad Acción de compilación para contener el valor GenerateDataContracts
- Construya el proyecto con el archivo XSD. Genera el primer archivo .g.cs.
- Controle la vista en el Explorador de soluciones para mostrar todos los archivos en el sistema de archivos.
- Incluya el nuevo archivo generado en el proyecto.
- Agregue referencia al ensamblado System.Runtime.Serialization.
Disfrutar.
<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>
En una máquina de 64 bits lo encontrarás en
%systemdrive%/Program Files (x86)/MSBuild/<version you use>
En este caso:
%systemdrive%/Program Files (x86)/MSBuild/4.0/Microsoft.Common.Targets/ImportAfter/
La herramienta xsd.exe
es anterior a WCF y no sabe nada sobre [DataContract]
y [DataMember]
. Si usa xsd.exe
, deberá cambiar WCF para usar XmlSerializer
lugar de DataContractSerializer
predeterminado para serializar los contratos de datos.
El equivalente de WCF para xsd.exe
es svcutil.exe
, tiene un parámetro /dconly
que crea los contratos de datos solamente, desde un archivo XSD dado. Esto generará un archivo C # o VB.NET para usted, que contiene los contratos de datos bien anotados.
Uso:
svcutil.exe (name of your XSD).xsd /dconly
Esto generaría un archivo * .cs por el mismo nombre base en su directorio.
En mi experiencia, svcutil.exe
es bastante exigente con sus estructuras XML, así que no se sorprenda si le ladra con toneladas de advertencias y / o errores.
Use svcutil.exe en lugar de xsd.exe
Cómo utilizar ? Vaya al menú Inicio -> Microsoft Visual Studio 2008 -> Herramientas de Visual Studio -> Símbolo del sistema de Visual Studio 2008
y Cambie el directorio que desea o cambie el directorio a donde está su xsd.
svcutil.exe /help
enumerará todas las opciones.
una de las opciones que utilizo para generar data consultarct es solo
svcutil.exe /target:code /n:*,[Your Company and Department].Common.DataTransferObjects /dataContractOnly /serializer:auto /importXmlTypes common.xsd /out:common.cs
¡Sigue codificando hava buenos días!