Gegevensoverdracht opgeven in servicecontracten
De Windows Communication Foundation (WCF) kan worden beschouwd als een berichteninfrastructuur. Servicebewerkingen kunnen berichten ontvangen, verwerken en verzenden. Berichten worden beschreven met behulp van bewerkingscontracten. Denk bijvoorbeeld aan het volgende contract.
[ServiceContract]
public interface IAirfareQuoteService
{
[OperationContract]
float GetAirfare(string fromCity, string toCity);
}
<ServiceContract()>
Public Interface IAirfareQuoteService
<OperationContract()>
Function GetAirfare(fromCity As String, toCity As String) As Double
End Interface
Hier accepteert de GetAirfare
bewerking een bericht met informatie over fromCity
en toCity
en retourneert vervolgens een bericht dat een getal bevat.
In dit onderwerp worden de verschillende manieren uitgelegd waarop een bewerkingscontract berichten kan beschrijven.
Berichten beschrijven met parameters
De eenvoudigste manier om een bericht te beschrijven, is door een parameterlijst en de retourwaarde te gebruiken. In het voorgaande voorbeeld zijn de fromCity
parameters en toCity
tekenreeksen gebruikt om het aanvraagbericht te beschrijven en is de retourwaarde float gebruikt om het antwoordbericht te beschrijven. Als de retourwaarde alleen niet voldoende is om een antwoordbericht te beschrijven, kunnen parameters worden gebruikt. De volgende bewerking heeft fromCity
bijvoorbeeld en toCity
in het aanvraagbericht en een getal in combinatie met een valuta in het antwoordbericht:
[OperationContract]
float GetAirfare(string fromCity, string toCity, out string currency);
<OperationContract()>
Function GetAirfare(fromCity As String, toCity As String) As Double
Daarnaast kunt u referentieparameters gebruiken om een parameteronderdeel van zowel de aanvraag als het antwoordbericht te maken. De parameters moeten typen zijn die kunnen worden geserialiseerd (geconverteerd naar XML). WCF maakt standaard gebruik van een onderdeel dat de DataContractSerializer klasse wordt genoemd om deze conversie uit te voeren. De meeste primitieve typen (zoals int
, string
, float
en DateTime
.) worden ondersteund. Door de gebruiker gedefinieerde typen moeten normaal gesproken een gegevenscontract hebben. Zie Gegevenscontracten gebruiken voor meer informatie.
public interface IAirfareQuoteService
{
[OperationContract]
float GetAirfare(Itinerary itinerary, DateTime date);
[DataContract]
public class Itinerary
{
[DataMember]
public string fromCity;
[DataMember]
public string toCity;
}
}
Public Interface IAirfareQuoteService
<OperationContract()>
GetAirfare(itinerary as Itinerary, date as DateTime) as Double
<DataContract()>
Class Itinerary
<DataMember()>
Public fromCity As String
<DataMember()>
Public toCity As String
End Class
End Interface
Af en toe is het DataContractSerializer
niet voldoende om uw typen te serialiseren. WCF ondersteunt een alternatieve serialisatie-engine, de XmlSerializer, die u ook kunt gebruiken om parameters te serialiseren. Hiermee XmlSerializer kunt u meer controle over de resulterende XML gebruiken met behulp van kenmerken zoals de XmlAttributeAttribute
. Als u wilt overschakelen naar het gebruik van de XmlSerializer voor een bepaalde bewerking of voor de hele service, past u het XmlSerializerFormatAttribute kenmerk toe op een bewerking of een service. Voorbeeld:
[ServiceContract]
public interface IAirfareQuoteService
{
[OperationContract]
[XmlSerializerFormat]
float GetAirfare(Itinerary itinerary, DateTime date);
}
public class Itinerary
{
public string fromCity;
public string toCity;
[XmlAttribute]
public bool isFirstClass;
}
<ServiceContract()>
Public Interface IAirfareQuoteService
<OperationContract()>
<XmlSerializerFormat>
GetAirfare(itinerary as Itinerary, date as DateTime) as Double
End Interface
Class Itinerary
Public fromCity As String
Public toCity As String
<XmlSerializerFormat()>
Public isFirstClass As Boolean
End Class
Zie De XmlSerializer-klasse gebruiken voor meer informatie. Houd er rekening mee dat handmatig overschakelen naar de XmlSerializer zoals hier wordt weergegeven, niet wordt aanbevolen, tenzij u specifieke redenen hebt om dit te doen, zoals beschreven in dat onderwerp.
Als u .NET-parameternamen wilt isoleren van contractnamen, kunt u het MessageParameterAttribute kenmerk gebruiken en de Name
eigenschap gebruiken om de contractnaam in te stellen. Het volgende bewerkingscontract is bijvoorbeeld gelijk aan het eerste voorbeeld in dit onderwerp.
[OperationContract]
public float GetAirfare(
[MessageParameter(Name="fromCity")] string originCity,
[MessageParameter(Name="toCity")] string destinationCity);
<OperationContract()>
Function GetAirfare(<MessageParameter(Name := "fromCity")> fromCity As String, <MessageParameter(Name := "toCity")> toCity As String) As Double
Lege berichten beschrijven
Een leeg aanvraagbericht kan worden beschreven door geen invoer- of verwijzingsparameters te hebben. Bijvoorbeeld in C#:
[OperationContract]
public int GetCurrentTemperature();
Bijvoorbeeld in Visual Basic:
<OperationContract()>
Function GetCurrentTemperature() as Integer
Een leeg antwoordbericht kan worden beschreven door een void
retourtype en geen uitvoer- of verwijzingsparameters te hebben. Bijvoorbeeld in:
[OperationContract]
public void SetTemperature(int temperature);
<OperationContract()>
Sub SetTemperature(temperature As Integer)
Dit verschilt van een eenrichtingsbewerking, zoals:
[OperationContract(IsOneWay=true)]
public void SetLightbulbStatus(bool isOn);
<OperationContract(IsOneWay:=True)>
Sub SetLightbulbStatus(isOne As Boolean)
De SetTemperatureStatus
bewerking retourneert een leeg bericht. Het kan in plaats daarvan een fout retourneren als er een probleem is met het verwerken van het invoerbericht. De SetLightbulbStatus
bewerking retourneert niets. Er is geen manier om een foutvoorwaarde van deze bewerking te communiceren.
Berichten beschrijven met behulp van berichtcontracten
U kunt één type gebruiken om het hele bericht weer te geven. Hoewel het mogelijk is om hiervoor een gegevenscontract te gebruiken, is de aanbevolen manier om dit te doen een berichtcontract te gebruiken. Dit voorkomt onnodige terugloopniveaus in de resulterende XML. Bovendien kunt u met berichtcontracten meer controle uitoefenen over resulterende berichten. U kunt bijvoorbeeld bepalen welke stukjes informatie in de hoofdtekst van het bericht moeten staan en welke in de berichtkoppen moeten staan. In het volgende voorbeeld ziet u het gebruik van berichtcontracten.
[ServiceContract]
public interface IAirfareQuoteService
{
[OperationContract]
GetAirfareResponse GetAirfare(GetAirfareRequest request);
}
[MessageContract]
public class GetAirfareRequest
{
[MessageHeader] public DateTime date;
[MessageBodyMember] public Itinerary itinerary;
}
[MessageContract]
public class GetAirfareResponse
{
[MessageBodyMember] public float airfare;
[MessageBodyMember] public string currency;
}
[DataContract]
public class Itinerary
{
[DataMember] public string fromCity;
[DataMember] public string toCity;
}
<ServiceContract()>
Public Interface IAirfareQuoteService
<OperationContract()>
Function GetAirfare(request As GetAirfareRequest) As GetAirfareResponse
End Interface
<MessageContract()>
Public Class GetAirfareRequest
<MessageHeader()>
Public Property date as DateTime
<MessageBodyMember()>
Public Property itinerary As Itinerary
End Class
<MessageContract()>
Public Class GetAirfareResponse
<MessageBodyMember()>
Public Property airfare As Double
<MessageBodyMember()> Public Property currency As String
End Class
<DataContract()>
Public Class Itinerary
<DataMember()> Public Property fromCity As String
<DataMember()> Public Property toCity As String
End Class
Zie Berichtcontracten gebruiken voor meer informatie.
In het vorige voorbeeld wordt de DataContractSerializer klasse nog steeds standaard gebruikt. De XmlSerializer klasse kan ook worden gebruikt met berichtcontracten. Hiervoor past u het XmlSerializerFormatAttribute kenmerk toe op de bewerking of het contract en gebruikt u typen die compatibel zijn met de XmlSerializer klasse in de berichtkoppen en hoofdteksten.
Berichten beschrijven met streams
Een andere manier om berichten in bewerkingen te beschrijven, is het gebruik van de Stream klasse of een van de afgeleide klassen in een bewerkingscontract of als lid van de berichtcontracttekst (dit moet het enige lid in dit geval zijn). Voor binnenkomende berichten moet het type zijn Stream
: u kunt geen afgeleide klassen gebruiken.
In plaats van de serialisatiefunctie aan te roepen, haalt WCF gegevens op uit een stream en plaatst deze rechtstreeks in een uitgaand bericht of haalt gegevens op uit een binnenkomend bericht en plaatst deze rechtstreeks in een stream. In het volgende voorbeeld ziet u het gebruik van streams.
[OperationContract]
public Stream DownloadFile(string fileName);
<OperationContract()>
Function DownloadFile(fileName As String) As String
U kunt gegevens niet combineren Stream
en niet streamen in één berichttekst. Gebruik een berichtcontract om de extra gegevens in berichtkoppen te plaatsen. In het volgende voorbeeld ziet u het onjuiste gebruik van streams bij het definiëren van het bewerkingscontract.
//Incorrect:
// [OperationContract]
// public void UploadFile (string fileName, Stream fileData);
'Incorrect:
'<OperationContract()>
Public Sub UploadFile(fileName As String, fileData As StreamingContext)
In het volgende voorbeeld ziet u het juiste gebruik van streams bij het definiëren van een bewerkingscontract.
[OperationContract]
public void UploadFile (UploadFileMessage message);
//code omitted
[MessageContract]
public class UploadFileMessage
{
[MessageHeader] public string fileName;
[MessageBodyMember] public Stream fileData;
}
<OperationContract()>
Public Sub UploadFile(fileName As String, fileData As StreamingContext)
'Code Omitted
<MessageContract()>
Public Class UploadFileMessage
<MessageHeader()>
Public Property fileName As String
<MessageBodyMember()>
Public Property fileData As Stream
End Class
Zie Large Data en Streaming voor meer informatie.
De berichtklasse gebruiken
Als u programmatische controle wilt hebben over berichten die zijn verzonden of ontvangen, kunt u de Message klasse rechtstreeks gebruiken, zoals wordt weergegeven in de volgende voorbeeldcode.
[OperationContract]
public void LogMessage(Message m);
<OperationContract()>
Sub LogMessage(m As Message)
Dit is een geavanceerd scenario, dat uitgebreid wordt beschreven in Het gebruik van de berichtklasse.
Foutberichten beschrijven
Naast de berichten die worden beschreven door de retourwaarde en uitvoer- of verwijzingsparameters, kan elke bewerking die niet in één richting is ten minste twee mogelijke berichten retourneren: het normale antwoordbericht en een foutbericht. Houd rekening met het volgende bewerkingscontract.
[OperationContract]
float GetAirfare(string fromCity, string toCity, DateTime date);
<OperationContract()>
Function GetAirfare(fromCity As String, toCity As String, date as DateTime)
Deze bewerking kan een normaal bericht met een float
getal of een foutbericht met een foutcode en een beschrijving retourneren. U kunt dit doen door een FaultException in uw service-implementatie te genereren.
U kunt aanvullende mogelijke foutberichten opgeven met behulp van het FaultContractAttribute kenmerk. De aanvullende fouten moeten serialiseerbaar zijn met behulp van de DataContractSerializer, zoals wordt weergegeven in de volgende voorbeeldcode.
[OperationContract]
[FaultContract(typeof(ItineraryNotAvailableFault))]
float GetAirfare(string fromCity, string toCity, DateTime date);
//code omitted
[DataContract]
public class ItineraryNotAvailableFault
{
[DataMember]
public bool IsAlternativeDateAvailable;
[DataMember]
public DateTime alternativeSuggestedDate;
}
<OperationContract()>
<FaultContract(GetType(ItineraryNotAvailableFault))>
Function GetAirfare(fromCity As String, toCity As String, date as DateTime) As Double
'Code Omitted
<DataContract()>
Public Class
<DataMember()>
Public Property IsAlternativeDateAvailable As Boolean
<DataMember()>
Public Property alternativeSuggestedDate As DateTime
End Class
Deze extra fouten kunnen worden gegenereerd door een FaultException<TDetail> van het juiste gegevenscontracttype te genereren. Zie Uitzonderingen en fouten afhandelen voor meer informatie.
U kunt de XmlSerializer klasse niet gebruiken om fouten te beschrijven. Het XmlSerializerFormatAttribute heeft geen effect op foutcontracten.
Afgeleide typen gebruiken
U kunt een basistype in een bewerking of een berichtcontract gebruiken en vervolgens een afgeleid type gebruiken wanneer u de bewerking daadwerkelijk aanroept. In dit geval moet u het ServiceKnownTypeAttribute kenmerk of een alternatief mechanisme gebruiken om het gebruik van afgeleide typen toe te staan. Houd rekening met de volgende bewerking.
[OperationContract]
public bool IsLibraryItemAvailable(LibraryItem item);
<OperationContract()>
Function IsLibraryItemAvailable(item As LibraryItem) As Boolean
Stel dat twee typen, Book
en Magazine
afgeleid zijn van LibraryItem
. Als u deze typen in de IsLibraryItemAvailable
bewerking wilt gebruiken, kunt u de bewerking als volgt wijzigen:
[OperationContract]
[ServiceKnownType(typeof(Book))]
[ServiceKnownType(typeof(Magazine))]
public bool IsLibraryItemAvailable(LibraryItem item);
U kunt ook het KnownTypeAttribute kenmerk gebruiken wanneer de standaardwaarde DataContractSerializer wordt gebruikt, zoals wordt weergegeven in de volgende voorbeeldcode.
[OperationContract]
public bool IsLibraryItemAvailable(LibraryItem item);
// code omitted
[DataContract]
[KnownType(typeof(Book))]
[KnownType(typeof(Magazine))]
public class LibraryItem
{
//code omitted
}
<OperationContract()>
Function IsLibraryItemAvailable(item As LibraryItem) As Boolean
'Code Omitted
<DataContract()>
<KnownType(GetType(Book))>
<KnownType(GetType(Magazine))>
Public Class LibraryItem
'Code Omitted
End Class
U kunt het XmlIncludeAttribute kenmerk gebruiken wanneer u de XmlSerializer.
U kunt het ServiceKnownTypeAttribute kenmerk toepassen op een bewerking of op de hele service. Het accepteert een type of de naam van de methode die moet worden aangeroepen om een lijst met bekende typen op te halen, net zoals het KnownTypeAttribute kenmerk. Zie Bekende typen gegevenscontracten voor meer informatie.
Het gebruik en de stijl opgeven
Bij het beschrijven van services met WSDL (Web Services Description Language), zijn de twee veelgebruikte stijlen Document- en Remote Procedure Call (RPC). In de documentstijl wordt de volledige berichttekst beschreven met behulp van het schema en de WSDL beschrijft de verschillende hoofdtekstonderdelen van het bericht door te verwijzen naar elementen in dat schema. In de RPC-stijl verwijst de WSDL naar een schematype voor elk berichtonderdeel in plaats van een element. In sommige gevallen moet u handmatig een van deze stijlen selecteren. U kunt dit doen door het DataContractFormatAttribute kenmerk toe te passen en de Style
eigenschap in te stellen (wanneer de DataContractSerializer eigenschap wordt gebruikt), of door het kenmerk in te XmlSerializerFormatAttribute stellen Style
(wanneer u het XmlSerializergebruikt).
Daarnaast ondersteunt de functie XmlSerializer twee vormen van geserialiseerde XML: Literal
en Encoded
. Literal
is het meest geaccepteerde formulier en is de enige vorm die door de DataContractSerializer ondersteuning wordt ondersteund. Encoded
is een verouderd formulier dat wordt beschreven in sectie 5 van de SOAP-specificatie en wordt niet aanbevolen voor nieuwe services. Als u wilt overschakelen naar Encoded
de modus, stelt u de Use
eigenschap van het XmlSerializerFormatAttribute kenmerk Encoded
in op .
In de meeste gevallen moet u de standaardinstellingen voor de Style
en Use
eigenschappen niet wijzigen.
Het serialisatieproces beheren
U kunt een aantal dingen doen om de manier aan te passen waarop gegevens worden geserialiseerd.
Serverserialisatie wijzigen Instellingen
Wanneer de standaardinstelling DataContractSerializer wordt gebruikt, kunt u bepaalde aspecten van het serialisatieproces op de service beheren door het ServiceBehaviorAttribute kenmerk toe te passen op de service. U kunt de eigenschap gebruiken om het MaxItemsInObjectGraph
quotum in te stellen dat het maximumaantal objecten beperkt dat deserialisaties DataContractSerializer beperkt. U kunt de IgnoreExtensionDataObject
eigenschap gebruiken om de functie voor het terugdraaien van versiebeheer uit te schakelen. Zie Beveiligingsoverwegingen voor gegevens voor meer informatie over quota. Zie Forward-Compatible Data Contracts voor meer informatie over round-tripping.
[ServiceBehavior(MaxItemsInObjectGraph=100000)]
public class MyDataService:IDataService
{
public DataPoint[] GetData()
{
// Implementation omitted
}
}
<ServiceBehavior(MaxItemsInObjectGraph:=100000)>
Public Class MyDataService Implements IDataService
Function GetData() As DataPoint()
‘ Implementation omitted
End Function
End Interface
Serialisatiegedrag
Er zijn twee gedragingen beschikbaar in WCF, de DataContractSerializerOperationBehavior en de XmlSerializerOperationBehavior die automatisch worden aangesloten, afhankelijk van welke serializer wordt gebruikt voor een bepaalde bewerking. Omdat dit gedrag automatisch wordt toegepast, hoeft u zich normaal gesproken niet bewust te zijn van deze gedragingen.
Het DataContractSerializerOperationBehavior
heeft echter de MaxItemsInObjectGraph
, IgnoreExtensionDataObject
en DataContractSurrogate
eigenschappen die u kunt gebruiken om het serialisatieproces aan te passen. De eerste twee eigenschappen hebben dezelfde betekenis als besproken in de vorige sectie. U kunt de DataContractSurrogate
eigenschap gebruiken om surrogaten voor gegevenscontracten in te schakelen. Dit is een krachtig mechanisme voor het aanpassen en uitbreiden van het serialisatieproces. Zie Data Contract Surrogates voor meer informatie.
U kunt de functie DataContractSerializerOperationBehavior
gebruiken om zowel client- als serverserialisatie aan te passen. In het volgende voorbeeld ziet u hoe u het MaxItemsInObjectGraph
quotum voor de client verhoogt.
ChannelFactory<IDataService> factory = new ChannelFactory<IDataService>(binding, address);
foreach (OperationDescription op in factory.Endpoint.Contract.Operations)
{
DataContractSerializerOperationBehavior dataContractBehavior =
op.Behaviors.Find<DataContractSerializerOperationBehavior>()
as DataContractSerializerOperationBehavior;
if (dataContractBehavior != null)
{
dataContractBehavior.MaxItemsInObjectGraph = 100000;
}
}
IDataService client = factory.CreateChannel();
Dim factory As ChannelFactory(Of IDataService) = New ChannelFactory(Of IDataService)(binding, address)
For Each op As OperationDescription In factory.Endpoint.Contract.Operations
Dim dataContractBehavior As DataContractSerializerOperationBehavior = op.Behaviors.Find(Of DataContractSerializerOperationBehavior)()
If dataContractBehavior IsNot Nothing Then
dataContractBehavior.MaxItemsInObjectGraph = 100000
End If
Next
Dim client As IDataService = factory.CreateChannel
Hier volgt de equivalente code voor de service, in het zelf-hostende geval:
ServiceHost serviceHost = new ServiceHost(typeof(IDataService))
foreach (ServiceEndpoint ep in serviceHost.Description.Endpoints)
{
foreach (OperationDescription op in ep.Contract.Operations)
{
DataContractSerializerOperationBehavior dataContractBehavior =
op.Behaviors.Find<DataContractSerializerOperationBehavior>()
as DataContractSerializerOperationBehavior;
if (dataContractBehavior != null)
{
dataContractBehavior.MaxItemsInObjectGraph = 100000;
}
}
}
serviceHost.Open();
Dim serviceHost As ServiceHost = New ServiceHost(GetType(IDataService))
For Each ep As ServiceEndpoint In serviceHost.Description.Endpoints
For Each op As OperationDescription In ep.Contract.Operations
Dim dataContractBehavior As DataContractSerializerOperationBehavior = op.Behaviors.Find(Of DataContractSerializerOperationBehavior)()
If dataContractBehavior IsNot Nothing Then
dataContractBehavior.MaxItemsInObjectGraph = 100000
End If
Next
Next
serviceHost.Open()
In het web-hostende geval moet u een nieuwe ServiceHost
afgeleide klasse maken en een servicehostfactory gebruiken om deze in te sluiten.
Serialisatie Instellingen in configuratie beheren
De MaxItemsInObjectGraph
en IgnoreExtensionDataObject
kunnen worden beheerd via configuratie met behulp van het dataContractSerializer
eindpunt of servicegedrag, zoals wordt weergegeven in het volgende voorbeeld.
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="LargeQuotaBehavior">
<dataContractSerializer
maxItemsInObjectGraph="100000" />
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="http://example.com/myservice"
behaviorConfiguration="LargeQuotaBehavior"
binding="basicHttpBinding" bindingConfiguration=""
contract="IDataService"
name="" />
</client>
</system.serviceModel>
</configuration>
Serialisatie van gedeelde typen, behoud van objectgrafieken en aangepaste serialisatiefuncties
De DataContractSerializer serialisaties maken gebruik van namen van gegevenscontract en niet van .NET-typenamen. Dit is consistent met servicegerichte architectuurtenets en biedt een grote mate van flexibiliteit: de .NET-typen kunnen veranderen zonder dat dit van invloed is op het wire contract. In zeldzame gevallen kunt u de werkelijke namen van .NET-typen serialiseren, waardoor er een nauwe koppeling tussen de client en de server ontstaat, vergelijkbaar met de externe technologie van .NET Framework. Dit is geen aanbevolen procedure, behalve in zeldzame gevallen die meestal optreden bij het migreren naar WCF vanaf externe communicatie van .NET Framework. In dit geval moet u de NetDataContractSerializer klasse gebruiken in plaats van de DataContractSerializer klasse.
Objectgrafieken DataContractSerializer worden normaal gesproken geserialiseerd als objectstructuren. Dat wil gezegd dat als hetzelfde object meerdere keren wordt verwezen, het meer dan één keer wordt geserialiseerd. Denk bijvoorbeeld aan een PurchaseOrder
exemplaar met twee velden van het type Adres aangeroepen billTo
en shipTo
. Als beide velden zijn ingesteld op hetzelfde adresexemplaren, zijn er twee identieke adresexemplaren na serialisatie en deserialisatie. Dit wordt gedaan omdat er geen standaard interoperabele manier is om objectgrafieken in XML weer te geven (met uitzondering van de verouderde soap-gecodeerde standaard die beschikbaar is op de XmlSerializer, zoals beschreven in de vorige sectie over Style
en Use
). Het serialiseren van objectgrafieken als bomen heeft bepaalde nadelen, bijvoorbeeld grafieken met kringverwijzingen kunnen niet worden geserialiseerd. Af en toe is het nodig om over te schakelen naar echte objectgrafiekserialisatie, ook al is het niet interoperabel. Dit kan worden gedaan met behulp van de DataContractSerializer samengestelde met de preserveObjectReferences
parameter die is ingesteld op true
.
Af en toe zijn de ingebouwde serializers niet voldoende voor uw scenario. In de meeste gevallen kunt u nog steeds de XmlObjectSerializer abstractie gebruiken waaruit zowel de DataContractSerializer als de NetDataContractSerializer afgeleid zijn.
Voor de vorige drie gevallen (.NET-typebehoud, objectgrafiekbehoud en volledig aangepaste XmlObjectSerializer
serialisatie) is een aangepaste serialisatiefunctie vereist. Voer hiervoor de volgende stappen uit:
Schrijf uw eigen gedrag dat is afgeleid van de DataContractSerializerOperationBehavior.
Overschrijf de twee
CreateSerializer
methoden om uw eigen serializer te retourneren (de NetDataContractSerializer, de DataContractSerializer metpreserveObjectReferences
ingesteld optrue
, of uw eigen aangepaste XmlObjectSerializer).Voordat u de servicehost opent of een clientkanaal maakt, verwijdert u het bestaande DataContractSerializerOperationBehavior gedrag en sluit u de aangepaste afgeleide klasse aan die u in de vorige stappen hebt gemaakt.
Zie Serialisatie en deserialisatie voor meer informatie over geavanceerde serialisatieconcepten.