Генерация DataContract из XSD - PullRequest
       24

Генерация DataContract из XSD

26 голосов
/ 03 февраля 2010

Я хочу иметь возможность генерировать DataContract из файла XSD, предпочтительно с помощью инструмента xsd.exe . Какой самый простой способ автоматически сгенерировать [DataContract] и [DataMember] для каждого из моих предметов?

Или есть лучший подход? Я пытаюсь избежать пересоздания контракта данных каждый раз, когда файл XSD изменяется и регенерируется.

Ответы [ 4 ]

44 голосов
/ 03 февраля 2010

Инструмент xsd.exe предшествует WCF и ничего не знает о [DataContract] и [DataMember]. Если вы используете xsd.exe, вам придется переключить WCF, чтобы использовать XmlSerializer вместо значения по умолчанию DataContractSerializer для сериализации контрактов данных.

Эквивалент WCF для xsd.exe равен svcutil.exe - у него есть параметр /dconly, который создает только контракты данных из данного файла XSD. Это сгенерирует для вас файл C # или VB.NET, содержащий хорошо помеченные контракты с данными.

Использование:

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

Это создаст файл * .cs с тем же базовым именем в вашем каталоге.

По моему опыту, svcutil.exe довольно требователен к своим XML-структурам, поэтому не удивляйтесь, если он лает на вас тоннами предупреждений и / или ошибок.

12 голосов
/ 30 ноября 2010

Используйте 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 голосов
/ 08 марта 2012

DataContracts от XSD первым!

Это современный способ и очень хорошая практика, однако 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>
1 голос
/ 15 сентября 2014

На 64-битной машине вы найдете его в

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

В этом случае:

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