Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Die Windows Communication Foundation (WCF) kann als Messaginginfrastruktur betrachtet werden. Dienstvorgänge können Nachrichten empfangen, verarbeiten und nachrichten senden. Nachrichten werden mithilfe von Betriebsverträgen beschrieben. Betrachten Sie z. B. den folgenden Vertrag.
[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 akzeptiert der GetAirfare-Vorgang eine Nachricht mit Informationen über fromCity und toCity und gibt dann eine Nachricht zurück, die eine Zahl enthält.
In diesem Thema werden die verschiedenen Möglichkeiten erläutert, wie ein Vorgangsvertrag Nachrichten beschreiben kann.
Beschreiben von Nachrichten mithilfe von Parametern
Die einfachste Möglichkeit zum Beschreiben einer Nachricht besteht darin, eine Parameterliste und den Rückgabewert zu verwenden. Im vorherigen Beispiel wurden die fromCity Parameter und toCity Zeichenfolgen zum Beschreiben der Anforderungsnachricht verwendet, und der Float-Rückgabewert wurde verwendet, um die Antwortnachricht zu beschreiben. Wenn der Rückgabewert allein nicht ausreicht, um eine Antwortnachricht zu beschreiben, können Ausgabeparameter verwendet werden. Im folgenden Vorgang befinden sich fromCity und toCity in der Anforderungsnachricht, und in der Antwortnachricht eine Zahl zusammen mit einer Währung.
[OperationContract]
float GetAirfare(string fromCity, string toCity, out string currency);
<OperationContract()>
Function GetAirfare(fromCity As String, toCity As String) As Double
Darüber hinaus können Sie Referenzparameter verwenden, um einen Parameterteil sowohl der Anforderung als auch der Antwortnachricht zu erstellen. Die Parameter müssen typen sein, die serialisiert werden können (in XML konvertiert). Standardmäßig verwendet WCF eine Komponente, die als DataContractSerializer Klasse bezeichnet wird, um diese Konvertierung auszuführen. Die meisten Grundtypen (zum Beispiel int, string, float und DateTime) werden unterstützt. Benutzerdefinierte Typen müssen normalerweise über einen Datenvertrag verfügen. Weitere Informationen finden Sie unter Verwenden von Datenverträgen.
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
Gelegentlich ist der DataContractSerializer nicht zur Serialisierung der Typen geeignet. WCF unterstützt die alternative Serialisierungs-Engine XmlSerializer, die Sie auch zur Serialisierung von Parametern verwenden können. Das XmlSerializer ermöglicht Ihnen größere Kontrolle über das resultierende XML durch die Verwendung von Attributen wie dem XmlAttributeAttribute. Um zur Verwendung XmlSerializer für einen bestimmten Vorgang oder für den gesamten Dienst zu wechseln, wenden Sie das XmlSerializerFormatAttribute Attribut auf einen Vorgang oder einen Dienst an. Beispiel:
[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
Weitere Informationen finden Sie unter Verwenden der XmlSerializer-Klasse. Vergessen Sie nicht, dass ein manueller Wechsel zum XmlSerializer, wie hier dargestellt, nicht empfohlen wird, wenn nicht triftige Gründe dafür vorliegen, wie sie in diesem Thema ausführlich beschrieben werden.
Um .NET-Parameternamen aus Vertragsnamen zu isolieren, können Sie das MessageParameterAttribute Attribut verwenden und die Name Eigenschaft verwenden, um den Vertragsnamen festzulegen. Der folgende Vorgangsvertrag entspricht beispielsweise dem ersten Beispiel in diesem Thema.
[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
Leere Nachrichten beschreiben
Eine leere Anforderungsnachricht kann beschrieben werden, indem keine Eingabe- oder Referenzparameter vorhanden sind. Beispiel: in C#:
[OperationContract]
public int GetCurrentTemperature();
Beispiel: in Visual Basic:
<OperationContract()>
Function GetCurrentTemperature() as Integer
Eine leere Antwortnachricht kann beschrieben werden, indem ein void Rückgabetyp und keine Ausgabe- oder Referenzparameter vorhanden sind. Zum Beispiel in:
[OperationContract]
public void SetTemperature(int temperature);
<OperationContract()>
Sub SetTemperature(temperature As Integer)
Dies unterscheidet sich von einem unidirektionalen Vorgang wie z. B.:
[OperationContract(IsOneWay=true)]
public void SetLightbulbStatus(bool isOn);
<OperationContract(IsOneWay:=True)>
Sub SetLightbulbStatus(isOne As Boolean)
Der SetTemperatureStatus Vorgang gibt eine leere Nachricht zurück. Es kann stattdessen einen Fehler zurückgeben, wenn ein Problem bei der Verarbeitung der Eingabemeldung vorliegt. Der SetLightbulbStatus Vorgang gibt nichts zurück. Es gibt keine Möglichkeit, einen Fehlerzustand durch diesen Vorgang zu kommunizieren.
Beschreiben von Nachrichten mithilfe von Nachrichtenverträgen
Möglicherweise möchten Sie einen einzelnen Typ verwenden, um die gesamte Nachricht darzustellen. Obwohl es möglich ist, einen Datenvertrag für diesen Zweck zu verwenden, empfiehlt es sich, einen Nachrichtenvertrag zu verwenden. Dadurch werden unnötige Umbruchstufen im resultierenden XML-Code vermieden. Darüber hinaus ermöglichen es Nachrichtenverträge, dir mehr Kontrolle über die resultierenden Nachrichten zu geben. Beispielsweise können Sie entscheiden, welche Informationen sich im Nachrichtentext befinden sollen und welche sich in den Nachrichtenkopfzeilen befinden sollen. Das folgende Beispiel zeigt die Verwendung von Nachrichtenverträgen.
[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
Weitere Informationen finden Sie unter Verwenden von Nachrichtenverträgen.
Im vorherigen Beispiel wird die DataContractSerializer Klasse weiterhin standardmäßig verwendet. Die XmlSerializer Klasse kann auch mit Nachrichtenverträgen verwendet werden. Wenden Sie dazu das XmlSerializerFormatAttribute Attribut entweder auf den Vorgang oder den Vertrag an, und verwenden Sie Typen, die mit der Klasse in den XmlSerializer Nachrichtenkopfzeilen und den Textkörperelementen kompatibel sind.
Beschreiben von Nachrichten mithilfe von Datenströmen
Eine weitere Möglichkeit zum Beschreiben von Nachrichten in Vorgängen besteht darin, die Stream Klasse oder eine ihrer abgeleiteten Klassen in einem Vorgangsvertrag oder als Nachrichtenvertragsmitglied zu verwenden (in diesem Fall muss es sich um das einzige Mitglied handeln). Bei eingehenden Nachrichten muss der Typ sein Stream– Sie können keine abgeleiteten Klassen verwenden.
Anstatt den Serialisierer aufzugeben, ruft WCF Daten aus einem Datenstrom ab und fügt sie direkt in eine ausgehende Nachricht ein, oder ruft Daten aus einer eingehenden Nachricht ab und fügt sie direkt in einen Datenstrom ein. Das folgende Beispiel zeigt die Verwendung von Datenströmen.
[OperationContract]
public Stream DownloadFile(string fileName);
<OperationContract()>
Function DownloadFile(fileName As String) As String
Sie können Stream-Daten und Nicht-Stream-Daten nicht in einem einzelnen Nachrichtentext kombinieren. Verwenden Sie einen Nachrichtenvertrag, um die zusätzlichen Daten in Nachrichtenkopfzeilen zu platzieren. Das folgende Beispiel zeigt die falsche Verwendung von Datenströmen beim Definieren des Vorgangsvertrags.
//Incorrect:
// [OperationContract]
// public void UploadFile (string fileName, Stream fileData);
'Incorrect:
'<OperationContract()>
Public Sub UploadFile(fileName As String, fileData As StreamingContext)
Das folgende Beispiel zeigt die richtige Verwendung von Datenströmen beim Definieren eines Vorgangsvertrags.
[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
Weitere Informationen finden Sie unter "Große Daten und Streaming".
Verwenden der Nachrichtenklasse
Um die programmgesteuerte Kontrolle über gesendete oder empfangene Nachrichten zu erhalten, können Sie die Message Klasse direkt verwenden, wie im folgenden Beispielcode gezeigt.
[OperationContract]
public void LogMessage(Message m);
<OperationContract()>
Sub LogMessage(m As Message)
Dies ist ein erweitertes Szenario, das in der Verwendung der Nachrichtenklasse ausführlich beschrieben wird.
Fehlermeldungsbeschreibung
Zusätzlich zu den Nachrichten, die durch den Rückgabewert und die Ausgabe- oder Referenzparameter beschrieben werden, kann jeder Vorgang, der nicht unidirektional ist, mindestens zwei mögliche Nachrichten zurückgeben: seine normale Antwortnachricht und eine Fehlermeldung. Betrachten Sie den folgenden Vorgangsvertrag.
[OperationContract]
float GetAirfare(string fromCity, string toCity, DateTime date);
<OperationContract()>
Function GetAirfare(fromCity As String, toCity As String, date as DateTime)
Dieser Vorgang kann entweder eine normale Nachricht zurückgeben, die eine float Zahl enthält, oder eine Fehlermeldung, die einen Fehlercode und eine Beschreibung enthält. Sie können dies erreichen, indem Sie eine FaultException in Ihre Service-Implementierung einfügen.
Sie können zusätzliche mögliche Fehlermeldungen mithilfe des FaultContractAttribute Attributs angeben. Die zusätzlichen Fehler müssen mithilfe des DataContractSerializerfolgenden Beispielcodes serialisierbar sein.
[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
Diese zusätzlichen Fehler können durch Auslösen einer FaultException<TDetail> des geeigneten Datenvertragstyps generiert werden. Weitere Informationen finden Sie unter Behandeln von Ausnahmen und Fehlern.
Sie können die XmlSerializer Klasse nicht verwenden, um Fehler zu beschreiben. Das XmlSerializerFormatAttribute hat keine Auswirkungen auf Fehlerverträge.
Verwenden abgeleiteter Typen
Sie können einen Basistyp in einem Vorgang oder einem Nachrichtenvertrag verwenden und dann einen abgeleiteten Typ verwenden, wenn Sie den Vorgang aufrufen. In diesem Fall müssen Sie entweder das ServiceKnownTypeAttribute Attribut oder einen alternativen Mechanismus verwenden, um die Verwendung abgeleiteter Typen zu ermöglichen. Betrachten Sie den folgenden Vorgang.
[OperationContract]
public bool IsLibraryItemAvailable(LibraryItem item);
<OperationContract()>
Function IsLibraryItemAvailable(item As LibraryItem) As Boolean
Gehen Sie davon aus, dass zwei Typen, Book und Magazine, von LibraryItem abgeleitet werden. Um diese Typen im IsLibraryItemAvailable Vorgang zu verwenden, können Sie den Vorgang wie folgt ändern:
[OperationContract]
[ServiceKnownType(typeof(Book))]
[ServiceKnownType(typeof(Magazine))]
public bool IsLibraryItemAvailable(LibraryItem item);
Alternativ können Sie das KnownTypeAttribute Attribut verwenden, wenn der Standardwert DataContractSerializer verwendet wird, wie im folgenden Beispielcode gezeigt.
[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
Sie können das XmlIncludeAttribute Attribut verwenden, wenn Sie das XmlSerializerAttribut verwenden.
Sie können das ServiceKnownTypeAttribute Attribut auf einen Vorgang oder auf den gesamten Dienst anwenden. Er akzeptiert entweder einen Typ oder den Namen der Methode, um eine Liste bekannter Typen abzurufen, genau wie das KnownTypeAttribute Attribut. Weitere Informationen finden Sie unter Datenvertrag: Bekannte Typen.
Angeben der Verwendung und des Stils
Bei der Beschreibung von Diensten mithilfe der Web Services Description Language (WSDL) sind die beiden häufig verwendeten Stile Dokument und Remote-Prozeduraufruf (RPC). Im Dokumentformat wird der gesamte Nachrichtentext mithilfe des Schemas beschrieben, und die WSDL beschreibt die verschiedenen Nachrichtentextteile, indem auf Elemente innerhalb dieses Schemas verwiesen wird. Im RPC-Stil bezieht sich die WSDL auf einen Schematyp für jeden Nachrichtenteil und nicht auf ein Element. In einigen Fällen müssen Sie eine dieser Formatvorlagen manuell auswählen. Sie können dies tun, indem Sie das DataContractFormatAttribute Attribut anwenden und die Style Eigenschaft festlegen (wenn sie DataContractSerializer verwendet wird), oder durch Festlegen Style des XmlSerializerFormatAttribute Attributs (bei Verwendung des Attributs XmlSerializer).
Darüber hinaus unterstützt das XmlSerializer zwei Formen von serialisiertem XML: Literal und Encoded. Literal ist das am häufigsten akzeptierte Formular und ist das einzige Formular, das DataContractSerializer unterstützt wird. Encoded ist ein älteres Formular, das in Abschnitt 5 der SOAP-Spezifikation beschrieben wird und für neue Dienste nicht empfohlen wird. Um in den Modus zu Encoded wechseln, legen Sie die Use Eigenschaft für das XmlSerializerFormatAttribute Attribut auf Encoded.
In den meisten Fällen sollten Sie die Standardeinstellungen für die Eigenschaften Style und Use nicht ändern.
Steuern des Serialisierungsprozesses
Sie können eine Reihe von Aktionen ausführen, um die Art und Weise anzupassen, wie Daten serialisiert werden.
Ändern der Server serialisierungseinstellungen
Wenn die Standardeinstellung DataContractSerializer verwendet wird, können Sie einige Aspekte des Serialisierungsprozesses für den Dienst steuern, indem Sie das ServiceBehaviorAttribute Attribut auf den Dienst anwenden. Insbesondere können Sie die MaxItemsInObjectGraph-Eigenschaft verwenden, um das Kontingent festzulegen, das die maximale Anzahl von Objekten, die DataContractSerializer deserialisiert, begrenzt. Sie können die IgnoreExtensionDataObject-Eigenschaft verwenden, um die Roundtrip-Versionsverwaltungsfunktion zu deaktivieren. Weitere Informationen zu Kontingenten finden Sie unter Sicherheitsaspekte für Daten. Weitere Informationen zum Roundtripping finden Sie unter Aufwärtskompatible Datenverträge.
[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
Serialisierungsverhalten
Zwei Verhaltensweisen sind in WCF verfügbar: die DataContractSerializerOperationBehavior und die XmlSerializerOperationBehavior, die je nach verwendeter Serialisierung für einen bestimmten Vorgang automatisch eingebunden werden. Da diese Verhaltensweisen automatisch angewendet werden, müssen Sie diese normalerweise nicht beachten.
Das DataContractSerializerOperationBehavior hat jedoch die Eigenschaften MaxItemsInObjectGraph, IgnoreExtensionDataObject und DataContractSurrogate, die Sie zum Anpassen des Serialisierungsprozesses verwenden können. Die ersten beiden Eigenschaften haben die gleiche Bedeutung wie im vorherigen Abschnitt erläutert. Sie können die DataContractSurrogate Eigenschaft verwenden, um Datenvertrags-Surrogates zu aktivieren, die ein leistungsstarker Mechanismus zum Anpassen und Erweitern des Serialisierungsprozesses sind. Weitere Informationen finden Sie unter Data Contract Surrogates.
Sie können die DataContractSerializerOperationBehavior zur Anpassung der Serialisierung sowohl auf Client- als auch auf Serverseite verwenden. Das folgende Beispiel zeigt, wie Sie das MaxItemsInObjectGraph Kontingent auf dem Client erhöhen.
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
Nachfolgend sehen Sie den entsprechenden Code für den Dienst im selbst gehosteten Fall:
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()
Falls er im Internet gehostet wird, müssen Sie eine neue abgeleitete ServiceHost-Klasse erstellen und die Diensthostfactory verwenden, um sie zu laden.
Steuern der Serialisierungseinstellungen in der Konfiguration
Die MaxItemsInObjectGraph und IgnoreExtensionDataObject können durch Konfiguration mithilfe des dataContractSerializer Endpunkts oder des Dienstverhaltens gesteuert werden, wie im folgenden Beispiel gezeigt.
<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>
Serialisierung von gemeinsamen Typen, Objektdiagrammbeibehaltung und benutzerdefinierte Serialisierungsprogramme
Das DataContractSerializer serialisiert mithilfe von Datenvertragsnamen und nicht mithilfe von .NET-Typnamen. Dies entspricht dienstorientierten Architektur-Tenets und ermöglicht ein hohes Maß an Flexibilität – die .NET-Typen können sich ändern, ohne den Drahtvertrag zu beeinträchtigen. In seltenen Fällen möchten Sie möglicherweise tatsächliche .NET-Typnamen serialisieren, wodurch eine enge Kopplung zwischen dem Client und dem Server eingeführt wird, ähnlich der .NET Framework-Remotingtechnologie. Dies ist keine empfohlene Methode, außer in seltenen Fällen, die in der Regel beim Migrieren von .NET Framework-Remoting zu WCF auftreten. In diesem Fall müssen Sie die NetDataContractSerializer Klasse anstelle der DataContractSerializer Klasse verwenden.
Das DataContractSerializer serialisiert normalerweise Objektgraphen als Objektbäume. Das heißt, wenn dasselbe Objekt mehrmals referenziert wird, wird es mehrmals serialisiert. Betrachten Sie z. B. eine PurchaseOrder-Instanz mit zwei Feldern vom Typ "Adresse", die billTo und shipTo genannt werden. Wenn beide Felder auf dieselbe Adressinstanz festgelegt sind, gibt es nach der Serialisierung und Deserialisierung zwei identische Adressinstanzen. Dies erfolgt, weil es kein interoperables Standardverfahren zur Darstellung von Objektdiagrammen in XML gibt (außer dem älteren SOAP-Codierungsstandard, der für XmlSerializer verfügbar ist, wie im vorigen Abschnitt über Style und Use beschrieben). Das Serialisieren von Objektdiagrammen als Bäume hat bestimmte Nachteile, beispielsweise können Diagramme mit zyklischen Referenzen nicht serialisiert werden. Gelegentlich ist es notwendig, zur Serialisierung des echten Objektdiagramms zu wechseln, auch wenn es nicht interoperabel ist. Dies kann durch Verwendung vom DataContractSerializer erfolgen, das mit dem preserveObjectReferences-Parameter konstruiert ist, der auf true festgelegt ist.
Gelegentlich reichen die integrierten Serialisierer für Ihr Szenario nicht aus. In den meisten Fällen können Sie immer noch die XmlObjectSerializer Abstraktion verwenden, von der sowohl die DataContractSerializer als auch die NetDataContractSerializer Ableitung erfolgen.
Die drei vorherigen Fälle (.NET-Typbeibehaltung, Objektdiagrammbeibehaltung und die vollkommen benutzerdefinierte XmlObjectSerializer-basierte Serialisierung) erfordern alle die Einbindung eines benutzerdefinierten Serialisierungsprogramms. Führen Sie dazu die folgenden Schritte aus:
Schreiben Sie ein eigenes Verhalten, das sich vom DataContractSerializerOperationBehavior herleitet.
Überschreiben Sie die beiden
CreateSerializer-Methoden, um Ihren eigenen Serialisierer zurückzugeben (entweder den NetDataContractSerializer, den DataContractSerializer mitpreserveObjectReferences, der auftruegesetzt ist, oder Ihren eigenen benutzerdefinierten XmlObjectSerializer).Bevor Sie den Diensthost öffnen oder einen Clientkanal erstellen, entfernen Sie das vorhandene DataContractSerializerOperationBehavior Verhalten, und schließen Sie die benutzerdefinierte abgeleitete Klasse an, die Sie in den vorherigen Schritten erstellt haben.
Weitere Informationen zu erweiterten Serialisierungskonzepten finden Sie unter Serialisierung und Deserialisierung.