Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
DataContract örneği, serileştirme, seri durumdan çıkarma, şema dışarı aktarma ve şema içeri aktarma gibi işlemlerin bir veri sözleşmesi vekil sınıfı kullanılarak nasıl özelleştirilebileceğini gösterir. Bu örnek, bir istemci ve sunucu senaryosunda verilerin seri hale getirildiği ve bir Windows Communication Foundation (WCF) istemcisi ile hizmeti arasında iletildiği bir vekilin nasıl kullanılacağını gösterir.
Uyarı
Bu örnek için kurulum yordamı ve derleme yönergeleri bu konunun sonunda yer alır.
Örnek aşağıdaki hizmet sözleşmesini kullanır:
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
[AllowNonSerializableTypes]
public interface IPersonnelDataService
{
[OperationContract]
void AddEmployee(Employee employee);
[OperationContract]
Employee GetEmployee(string name);
}
bu AddEmployee
işlem, kullanıcıların yeni çalışanlar hakkında veri eklemesine olanak tanır ve GetEmployee
işlem, ad temelinde çalışanları aramayı destekler.
Bu işlemler aşağıdaki veri türünü kullanır:
[DataContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
class Employee
{
[DataMember]
public DateTime dateHired;
[DataMember]
public Decimal salary;
[DataMember]
public Person person;
}
Employee
türünde, Person
sınıfı (aşağıdaki örnek kodda gösterilmiştir) geçerli bir veri sözleşmesi sınıfı olmadığından tarafından DataContractSerializer serileştirilemez.
public class Person
{
public string firstName;
public string lastName;
public int age;
public Person() { }
}
DataContractAttribute özniteliğini Person
sınıfına uygulayabilirsiniz, ancak bu her zaman mümkün değildir. Örneğin, bu sınıf üzerinde Person
denetiminiz olmayan ayrı bir bütünlemede tanımlanabilir.
Bu kısıtlama göz önüne alındığında, Person
sınıfını seri hale getirmenin bir yolu, önce onu DataContractAttribute ile işaretlenmiş başka bir sınıfla değiştirmek ve ardından gerekli verileri yeni sınıfa kopyalamaktır. Amaç, Person
sınıfının DataContractSerializer için bir DataContract olarak görünmesini sağlamaktır. Bunun, veri olmayan anlaşma sınıflarını seri hale getirmenin bir yolu olduğunu unutmayın.
Örnek, Person
sınıfını mantıksal olarak PersonSurrogated
adlı farklı bir sınıfla değiştirir.
[DataContract(Name="Person", Namespace = "http://Microsoft.ServiceModel.Samples")]
public class PersonSurrogated
{
[DataMember]
public string FirstName;
[DataMember]
public string LastName;
[DataMember]
public int Age;
}
Bu değişikliği gerçekleştirmek için veri sözleşmesi vekili kullanılır. Veri sözleşmesi vekili, IDataContractSurrogate arabirimini/şablonunu uygulayan bir sınıftır. Bu örnekte AllowNonSerializableTypesSurrogate
sınıfı bu arabirimi uygular.
Arabirim uygulamasında, ilk görev Person
ile PersonSurrogated
arasında bir tür eşlemesi oluşturmaktır. Bu hem serileştirme zamanında hem de şema dışarı aktarma zamanında kullanılır. Bu eşleme, GetDataContractType(Type) yöntemi uygulanarak gerçekleştirilir.
public Type GetDataContractType(Type type)
{
if (typeof(Person).IsAssignableFrom(type))
{
return typeof(PersonSurrogated);
}
return type;
}
Yöntem, serileştirme sırasında bir GetObjectToSerialize(Object, Type) örneğini bir Person
örneğine eşleştirir, aşağıdaki örnek kodda gösterildiği gibi.
public object GetObjectToSerialize(object obj, Type targetType)
{
if (obj is Person)
{
Person person = (Person)obj;
PersonSurrogated personSurrogated = new PersonSurrogated();
personSurrogated.FirstName = person.firstName;
personSurrogated.LastName = person.lastName;
personSurrogated.Age = person.age;
return personSurrogated;
}
return obj;
}
Bu GetDeserializedObject(Object, Type) yöntemi, aşağıdaki örnek kodda gösterildiği gibi seri durumdan çıkarma için ters eşleme sağlar.
public object GetDeserializedObject(object obj,
Type targetType)
{
if (obj is PersonSurrogated)
{
PersonSurrogated personSurrogated = (PersonSurrogated)obj;
Person person = new Person();
person.firstName = personSurrogated.FirstName;
person.lastName = personSurrogated.LastName;
person.age = personSurrogated.Age;
return person;
}
return obj;
}
Veri sözleşmesini şema içeri aktarımı sırasında mevcut PersonSurrogated
sınıfla eşlemek için Person
yöntemi, aşağıdaki örnek kodda gösterildiği gibi uygulanır.
public Type GetReferencedTypeOnImport(string typeName,
string typeNamespace, object customData)
{
if (
typeNamespace.Equals("http://schemas.datacontract.org/2004/07/DCSurrogateSample")
)
{
if (typeName.Equals("PersonSurrogated"))
{
return typeof(Person);
}
}
return null;
}
Aşağıdaki örnek kod arabiriminin IDataContractSurrogate uygulamasını tamamlar.
public System.CodeDom.CodeTypeDeclaration ProcessImportedType(
System.CodeDom.CodeTypeDeclaration typeDeclaration,
System.CodeDom.CodeCompileUnit compileUnit)
{
return typeDeclaration;
}
public object GetCustomDataToExport(Type clrType,
Type dataContractType)
{
return null;
}
public object GetCustomDataToExport(
System.Reflection.MemberInfo memberInfo, Type dataContractType)
{
return null;
}
public void GetKnownCustomDataTypes(
KnownTypeCollection customDataTypes)
{
// It does not matter what we do here.
throw new NotImplementedException();
}
Bu örnekte, vekil ServiceModel'de adlı AllowNonSerializableTypesAttribute
bir öznitelik tarafından etkinleştirilir. Geliştiricilerin bu özniteliği yukarıdaki hizmet sözleşmesinde gösterildiği gibi hizmet sözleşmelerine IPersonnelDataService
uygulaması gerekir. Bu öznitelik IContractBehavior
uygular ve ApplyClientBehavior
ile ApplyDispatchBehavior
yöntemlerindeki işlemlerde vekili ayarlar.
Bu örnekte özniteliği gerekli değildir; bu örnekte gösterim amacıyla kullanılır. Kullanıcılar, yerine geçen bir öğeyi alternatif olarak, benzer bir IContractBehavior
, IEndpointBehavior
veya IOperationBehavior
'yi el ile ekleyerek, kod kullanarak veya yapılandırma kullanarak etkinleştirebilir.
Uygulama, IContractBehavior
kayıtlı olup olmadığını DataContractSerializerOperationBehavior
denetleyerek DataContract kullanan işlemleri arar. Bunu yaparlarsa, DataContractSurrogate
özelliği o davranışa ayarlar. Aşağıdaki örnek kod, bunun nasıl yapıldığını gösterir. Bu işlem davranışına vekilin ayarlanması, serileştirme ve seri durumdan çıkarma için etkinleştirilmesini sağlar.
public void ApplyClientBehavior(ContractDescription description, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime proxy)
{
foreach (OperationDescription opDesc in description.Operations)
{
ApplyDataContractSurrogate(opDesc);
}
}
public void ApplyDispatchBehavior(ContractDescription description, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatch)
{
foreach (OperationDescription opDesc in description.Operations)
{
ApplyDataContractSurrogate(opDesc);
}
}
private static void ApplyDataContractSurrogate(OperationDescription description)
{
DataContractSerializerOperationBehavior dcsOperationBehavior = description.Behaviors.Find<DataContractSerializerOperationBehavior>();
if (dcsOperationBehavior != null)
{
if (dcsOperationBehavior.DataContractSurrogate == null)
dcsOperationBehavior.DataContractSurrogate = new AllowNonSerializableTypesSurrogate();
}
}
Meta veri oluşturma sırasında kullanılacak vekili takmak için ek adımlar atılması gerekir. Bunu yapmanın bir yolu, bu örneğin gösterdiği IWsdlExportExtension
sağlamaktır. Başka bir yöntem, WsdlExporter
öğesini doğrudan değiştirmektir.
AllowNonSerializableTypesAttribute
özniteliği IWsdlExportExtension
ve IContractBehavior
'yi uygular. Uzantı, bu durumda ya bir IContractBehavior
ya da bir IEndpointBehavior
olabilir. Yöntem IWsdlExportExtension.ExportContract
uygulaması, DataContract için şema oluşturma sırasında kullanılan XsdDataContractExporter
'e vekili ekleyerek etkinleştirir. Aşağıdaki kod parçacığı bunun nasıl yapılacağını gösterir.
public void ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)
{
if (exporter == null)
throw new ArgumentNullException("exporter");
object dataContractExporter;
XsdDataContractExporter xsdDCExporter;
if (!exporter.State.TryGetValue(typeof(XsdDataContractExporter), out dataContractExporter))
{
xsdDCExporter = new XsdDataContractExporter(exporter.GeneratedXmlSchemas);
exporter.State.Add(typeof(XsdDataContractExporter), xsdDCExporter);
}
else
{
xsdDCExporter = (XsdDataContractExporter)dataContractExporter;
}
if (xsdDCExporter.Options == null)
xsdDCExporter.Options = new ExportOptions();
if (xsdDCExporter.Options.DataContractSurrogate == null)
xsdDCExporter.Options.DataContractSurrogate = new AllowNonSerializableTypesSurrogate();
}
Örneği çalıştırdığınızda, istemci AddEmployee'yi ve ardından getEmployee çağrısını çağırarak ilk çağrının başarılı olup olmadığını denetler. GetEmployee işlem isteğinin sonucu istemci konsolu penceresinde görüntülenir. GetEmployee işleminin çalışanı bulmada başarılı olması ve "bulundu" yazdırması gerekir.
Uyarı
Bu örnek, serileştirme, serileştirmeden çıkarma ve meta veri oluşturma için bir vekilin nasıl eklendiğini gösterir. Meta verilerden kod oluşturma için bir vekilin nasıl bağlandığını göstermez. Bir vekilin istemci kodu oluşturma işlemine bağlanmak için nasıl kullanılabileceğini gösteren bir örnek görmek için bkz. Özel WSDL Yayını örneği.
Örneği ayarlamak, derlemek ve çalıştırmak için
Windows Communication Foundation Örnekleri içinOne-Time Kurulum Yordamını yaptığınızdan emin olun.
Çözümün C# sürümünü oluşturmak için Windows Communication Foundation Örnekleri Oluşturma başlığındaki yönergeleri izleyin.
Örneği tek bir makine veya makineler arası bir yapılandırmada çalıştırmak için, Windows Communication Foundation örneklerini çalıştırmayönergelerini izleyin.