2010-02-03 10 views
26

Quiero poder generar un DataContract de un archivo XSD, preferiblemente usando el xsd.exe tool. ¿Cuál es la forma más fácil de generar automáticamente [DataContract] y [DataMember] en cada uno de mis artículos?Generar DataContract de XSD

¿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.

+0

Ok ahora estoy recibiendo otro error. maxOcurrencias en DownloadRequestItem debe ser 1 Este es mi esquema \t elementFormDefault = "calificado"> \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

¿Puedes actualizar tu pregunta original editando? Poner XML en los comentarios es REALMENTE REALMENTE difícil de leer y un desastre ..... –

+0

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

Respuesta

42

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 el XmlSerializer en lugar de su predeterminado DataContractSerializer para serializar los contratos de datos.

El equivalente WCF para xsd.exe es svcutil.exe - que tiene un parámetro /dconly que crea los contratos de datos única, a partir de 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.

+0

Gracias, no sabía que esta herramienta existía – Daveo

+0

* bastante exigente con sus estructuras XML *: aquí se documenta lo que DCS soporta y lo que no. https://msdn.microsoft.com/en-us/library/ms733112 (v = vs.110) .aspx –

11

Uso svcutil.exe en lugar de xsd.exe

Cómo utilizar? Vaya al menú Inicio -> Microsoft Visual Studio 2008 -> Herramientas de Visual Studio -> Visual Studio 2008 Command Prompt

y cambie el directorio que desee o cambie el directorio a donde está su xsd.

svcutil.exe /help 

enumerará todas las opciones.

una de las opciones que utilizo para generar contarct datos sólo es

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

Mantenga hava de codificación buen día!

3

DataContracts from XSD first!

Es la forma moderna y muy buena práctica, sin embargo, VS2010 tiene soporte de automatización muy limitado por ello. Por lo tanto, me senté y escribí un objetivo de msbuild puro que: no requiere modificaciones de archivo de proyecto 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: \ Archivos de programa \ 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:

  • VS2010 reinicio y añadir un XSD en 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
  • Cree 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.

Enjoy.

<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

Su solución es interesante, pero "C: \ Archivos de programa \ MSBuild \ 4.0 \ Microsoft.Common.targets \ ImportAfter" No veo esa carpeta en mi computadora. – Serge

+1

@Serge, ** Suposiciones ** es que usa MSBuild de .NET4 y VS2010, en este caso simplemente cree las carpetas que faltan y guarde el archivo de objetivos allí (msbuild internaly busca esta ubicación). Esta solución también podría funcionar con la versión anterior de MSBuild, si se proporcionaran los cambios apropiados. – pavelz

1

En una máquina de 64 bits se encuentra en

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

En este caso:

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