Средство первого контакта
Контракты службы часто приходится создавать из существующих служб. В платформа .NET Framework 4.5 и более поздних версий классы контрактов данных можно создавать автоматически из существующих служб с помощью средства контракта. Для использования данного средства файл определения схемы XML (XSD) необходимо загрузить локально. Программа не может импортировать удаленные контракты данных через HTTP.
Средство для создания контракта интегрировано в Visual Studio 2012 в качестве задачи сборки. Файлы кода, формируемые задачей сборки, создаются при каждой сборке проекта, поэтому в проекте сразу же отражаются изменения в базовом контракте службы.
Типы схем, которые может импортировать средство разработки на основе контракта:
<xsd:complexType>
<xsd:simpleType>
</xsd:simpleType>
</xsd:complexType>
Простые типы не создаются, если они являются примитивами, например Int16
или String
, сложные типы не создаются, если они имеют тип Collection
. Типы также не создаются, если они являются частью другого xsd:complexType
. Во всех этих случаях данные типы ссылаются на существующие в проекте типы.
Добавление в проект контракта данных
Перед использованием средства на основе контракта в проект следует добавить контракт службы (XSD). В качестве наглядного примера будет использоваться следующий контракт. Это определение службы представляет собой небольшое подмножество контракта службы, используемого API поиска Bing.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="ServiceSchema"
targetNamespace="http://tempuri.org/ServiceSchema.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/ServiceSchema.xsd"
xmlns:mstns="http://tempuri.org/ServiceSchema.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:complexType name="SearchRequest">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="Version" type="xs:string" default="2.2" />
<xs:element minOccurs="0" maxOccurs="1" name="Market" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="UILanguage" type="xs:string" />
<xs:element minOccurs="1" maxOccurs="1" name="Query" type="xs:string" />
<xs:element minOccurs="1" maxOccurs="1" name="AppId" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="Latitude" type="xs:double" />
<xs:element minOccurs="0" maxOccurs="1" name="Longitude" type="xs:double" />
<xs:element minOccurs="0" maxOccurs="1" name="Radius" type="xs:double" />
</xs:sequence>
</xs:complexType>
<xs:simpleType name="WebSearchOption">
<xs:restriction base="xs:string">
<xs:enumeration value="DisableHostCollapsing" />
<xs:enumeration value="DisableQueryAlterations" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
Чтобы добавить приведенный выше контракт службы в проект, щелкните проект правой кнопкой мыши и нажмите кнопку "Добавить". Выберите определение схемы на панели WCF диалогового окна «Шаблоны» и присвойте новому файлу имя SampleContract.xsd. Скопируйте и вставьте приведенный выше код в новый файл.
Настройка параметров на основе контракта
Параметры контракта можно настроить в меню "Свойства" проекта WCF. Чтобы включить разработку с контрактом, выберите поле "Включить XSD в качестве языка определения типов" проверка на странице WCF окна свойств проекта.
Чтобы настроить дополнительные свойства, нажмите кнопку «Дополнительно».
Для создания кода на основе контракта можно установить следующие дополнительные параметры. Можно задать параметры только сразу для всех файлов в проекте. В настоящий момент нельзя задавать параметры для отдельных файлов.
Режим сериализатора: этот параметр определяет, какой сериализатор используется для чтения файлов контракта службы. При выборе сериализатора XML параметры типов коллекции и повторного использования отключены. Эти параметры применяются только к сериализатору контракта данных.
Повторное использование типов: этот параметр указывает, какие библиотеки используются для повторного использования типов. Этот параметр применяется только в том случае, если для сериализатора контракта данных задан режим сериализатора сериализатора контракта данных.
Тип коллекции: этот параметр указывает полный или полный тип, используемый для типа данных коллекции. Этот параметр применяется только в том случае, если для сериализатора контракта данных задан режим сериализатора сериализатора контракта данных.
Тип словаря: этот параметр указывает полный или сборочный тип, используемый для типа данных словаря.
EnableDataBinding: этот параметр указывает, следует ли реализовать интерфейс для всех типов данных для реализации INotifyPropertyChanged привязки данных.
Исключенные типы:Этот параметр указывает список полных или сборочных типов, которые следует исключить из ссылочных сборок. Этот параметр применяется только в том случае, если для сериализатора контракта данных задан режим сериализатора сериализатора контракта данных.
GenerateInternalTypes: этот параметр указывает, следует ли создавать классы, помеченные как внутренние. Этот параметр применяется только в том случае, если для сериализатора контракта данных задан режим сериализатора сериализатора контракта данных.
GenerateSerializableTypes: этот параметр указывает, следует ли создавать классы с помощью атрибута SerializableAttribute . Этот параметр применяется только в том случае, если для сериализатора контракта данных задан режим сериализатора сериализатора контракта данных.
ImportXMLTypes: этот параметр указывает, следует ли настроить сериализатор контракта данных для применения SerializableAttribute атрибута к классам без атрибута DataContractAttribute . Этот параметр применяется только в том случае, если для сериализатора контракта данных задан режим сериализатора сериализатора контракта данных.
SupportFx35TypedDataSets: этот параметр указывает, следует ли предоставлять дополнительные функции для типизированных наборов данных, созданных для платформа .NET Framework 3.5. Если для режима сериализатора задано значение XML Serializer, TypedDataSetSchemaImporterExtensionFx35 расширение будет добавлено в средство импорта схемы XML, если это значение имеет значение True. Если для сериализатора контракта данных задан режим сериализатора контракта данных, тип DateTimeOffset будет исключен из ссылок, если это значение имеет значение False, чтобы DateTimeOffset всегда создаваться для более старых версий платформы.
InputXsdFiles: этот параметр задает список входных файлов. Каждый файл должен содержать допустимую схему XML.
Язык: этот параметр задает язык созданного кода контракта. Параметр должен быть распознаваемым методом CodeDomProvider.
NamespaceMappings: этот параметр задает сопоставления из пространств имен XSD с пространствами имен CLR. В каждом сопоставлении необходимо использовать следующий формат:
"Schema Namespace, CLR Namespace"
Сериализатор XML принимает только одно сопоставление в следующем формате:
"*, CLR Namespace"
OutputDirectory: этот параметр указывает каталог, в котором будут создаваться файлы кода.
Параметры будут использоваться при построении проекта для создания типов контракта службы из файлов контракта службы.
Разработка на основе контракта
После добавления контракта службы в проект и подтверждения параметров сборки создайте проект, нажав клавишу F6. Типы, определенные в контракте службы, становятся доступными для использования в проекте.
Для использования типов, определенных в контракте службы, добавьте ссылку на ContractTypes
в текущем пространстве имен.
using MyProjectNamespace.ContractTypes;
Затем типы, определенные в контракте службы, будут разрешаться в проекте, как показано ниже:
Типы, созданные с помощью средства, помещаются в файл GeneratedXSDTypes.cs. Файл создается в каталоге <>проекта/obj/<build configuration>/XSDGeneratedCode/directory по умолчанию. Пример схемы в начале этой статьи преобразуется следующим образом:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.17330
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace TestXSD3.ContractTypes
{
using System.Xml.Serialization;
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.17330")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/ServiceSchema.xsd")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://tempuri.org/ServiceSchema.xsd", IsNullable=true)]
public partial class SearchRequest
{
private string versionField;
private string marketField;
private string uILanguageField;
private string queryField;
private string appIdField;
private double latitudeField;
private bool latitudeFieldSpecified;
private double longitudeField;
private bool longitudeFieldSpecified;
private double radiusField;
private bool radiusFieldSpecified;
public SearchRequest()
{
this.versionField = "2.2";
}
/// <remarks/>
[System.ComponentModel.DefaultValueAttribute("2.2")]
public string Version
{
get
{
return this.versionField;
}
set
{
this.versionField = value;
}
}
/// <remarks/>
public string Market
{
get
{
return this.marketField;
}
set
{
this.marketField = value;
}
}
/// <remarks/>
public string UILanguage
{
get
{
return this.uILanguageField;
}
set
{
this.uILanguageField = value;
}
}
/// <remarks/>
public string Query
{
get
{
return this.queryField;
}
set
{
this.queryField = value;
}
}
/// <remarks/>
public string AppId
{
get
{
return this.appIdField;
}
set
{
this.appIdField = value;
}
}
/// <remarks/>
public double Latitude
{
get
{
return this.latitudeField;
}
set
{
this.latitudeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool LatitudeSpecified
{
get
{
return this.latitudeFieldSpecified;
}
set
{
this.latitudeFieldSpecified = value;
}
}
/// <remarks/>
public double Longitude
{
get
{
return this.longitudeField;
}
set
{
this.longitudeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool LongitudeSpecified
{
get
{
return this.longitudeFieldSpecified;
}
set
{
this.longitudeFieldSpecified = value;
}
}
/// <remarks/>
public double Radius
{
get
{
return this.radiusField;
}
set
{
this.radiusField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool RadiusSpecified
{
get
{
return this.radiusFieldSpecified;
}
set
{
this.radiusFieldSpecified = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.17330")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/ServiceSchema.xsd")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://tempuri.org/ServiceSchema.xsd", IsNullable=false)]
public enum WebSearchOption
{
/// <remarks/>
DisableHostCollapsing,
/// <remarks/>
DisableQueryAlterations,
}
}
Ошибки и предупреждения
Ошибки и предупреждения, обнаруженные во время синтаксического анализа схемы XSD, появляются в виде ошибок и предупреждений сборки.
Наследование интерфейса
С разработкой на основе контракта нельзя использовать наследование интерфейса. Это согласуется с тем, как интерфейсы действуют в других операциях. Чтобы использовать интерфейс, который наследует базовый интерфейс, используйте две отдельные конечные точки. Первая конечная точка использует унаследованный контракт, вторая реализует базовый интерфейс.