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.
Das Datenvertrags-Surrogate ist ein erweitertes Feature, das auf dem Datenvertragsmodell basiert. Dieses Feature wurde für die Typanpassung und Ersetzung in Situationen verwendet, in denen Benutzer ändern möchten, wie ein Typ serialisiert, deserialisiert oder in Metadaten projiziert wird. Einige Szenarien, in denen ein Ersatz verwendet werden kann, besteht darin, dass ein Datenvertrag für den Typ nicht angegeben wurde, Felder und Eigenschaften nicht mit dem DataMemberAttribute Attribut gekennzeichnet sind oder Benutzer dynamisch Schemavariationen erstellen möchten.
Serialisierung und Deserialisierung werden mit dem Datenvertrag-Ersatzzeichen erreicht, wenn DataContractSerializer zum Konvertieren aus .NET Framework in ein geeignetes Format, wie z. B. XML, verwendet wird. Datenvertrags-Ersatz kann auch verwendet werden, um die für Typen exportierten Metadaten zu ändern, wenn Metadatendarstellungen wie XML-Schemadokumente (XSD) erstellt werden. Beim Import wird Code aus Metadaten erstellt, und der Ersatz kann in diesem Fall verwendet werden, um den generierten Code auch anzupassen.
Funktionsweise des Surrogates
Ein Stellvertreter funktioniert, indem ein Typ (der "Originaltyp") einem anderen Typ zugeordnet wird (dem "Ersatztyp"). Das folgende Beispiel zeigt den ursprünglichen Typ Inventory und einen neuen Ersatztyp InventorySurrogated . Der Inventory Typ ist nicht serialisierbar, aber der InventorySurrogated Typ lautet:
public class Inventory
{
public int pencils;
public int pens;
public int paper;
}
Da für diese Klasse kein Datenvertrag definiert wurde, konvertieren Sie die Klasse in eine Ersatzklasse mit einem Datenvertrag. Die Ersatzklasse wird im folgenden Beispiel gezeigt:
[DataContract(Name = "Inventory")]
public class InventorySurrogated
{
[DataMember]
public int numpencils;
[DataMember]
public int numpaper;
[DataMember]
private int numpens;
public int pens
{
get { return numpens; }
set { numpens = value; }
}
}
Implementieren des IDataContractSurrogate
Um das Datenvertrags-Surrogate zu verwenden, implementieren Sie die IDataContractSurrogate Schnittstelle.
Nachfolgend sehen Sie eine Übersicht über die einzelnen Methoden IDataContractSurrogate mit einer möglichen Implementierung.
GetDataContractType
Die GetDataContractType Methode ordnet einen Typ einem anderen zu. Diese Methode ist für serialisierung, Deserialisierung, Import und Export erforderlich.
Die erste Aufgabe definiert, welche Typen anderen Typen zugeordnet werden. Beispiel:
public Type GetDataContractType(Type type)
{
Console.WriteLine("GetDataContractType");
if (typeof(Inventory).IsAssignableFrom(type))
{
return typeof(InventorySurrogated);
}
return type;
}
Bei der Serialisierung wird die von dieser Methode zurückgegebene Zuordnung anschließend verwendet, um die ursprüngliche Instanz durch Aufrufen der GetObjectToSerialize Methode in eine surrogatete Instanz zu transformieren.
Bei der Deserialisierung wird die durch diese Methode zurückgegebene Zuordnung durch das Serialisierungsprogramm verwendet, um die Deserialisierung in eine Instanz des Ersatzzeichentyps durchzuführen. Anschließend wird GetDeserializedObject aufgerufen, um die surrogatete Instanz in eine Instanz des ursprünglichen Typs zu transformieren.
Beim Export wird der Ersatztyp, den diese Methode zurückgibt, verwendet, um den für die Metadaten-Generierung zu verwendenden Datenvertrag zu bestimmen.
Beim Import wird der Ausgangstyp in einen Ersatzzeichentyp geändert und reflektiert, um den Datenvertrag, der für Zwecke wie den Support-Verweis verwendet werden soll, zu erhalten.
Der Type Parameter ist der Typ des Objekts, das serialisiert, deserialisiert, importiert oder exportiert wird. Die GetDataContractType Methode muss den Eingabetyp zurückgeben, wenn der Ersatz den Typ nicht verarbeitet. Geben Sie andernfalls den entsprechenden Ersatztyp zurück. Wenn mehrere Ersatztypen vorhanden sind, können in dieser Methode zahlreiche Zuordnungen definiert werden.
Die GetDataContractType Methode wird nicht für integrierte Datenvertragsprimitive wie Int32 oder String aufgerufen. Für andere Typen, z. B. Arrays, benutzerdefinierte Typen und andere Datenstrukturen, wird diese Methode für jeden Typ aufgerufen.
Im vorherigen Beispiel überprüft die Methode, ob der Parameter type und Inventory vergleichbar sind. Wenn ja, mappt die Methode es zu InventorySurrogated. Immer wenn eine Serialisierung, Deserialisierung, Importschema oder Exportschema aufgerufen wird, wird diese Funktion zuerst aufgerufen, um die Zuordnung zwischen Typen zu bestimmen.
GetObjectToSerialize-Methode
Die GetObjectToSerialize Methode konvertiert die ursprüngliche Typinstanz in die Instanz des ersatzierten Typs. Die Methode ist für die Serialisierung erforderlich.
Der nächste Schritt besteht darin zu definieren, wie die physikalischen Daten von der ursprünglichen Instanz zur Ersatzzeicheninstanz erfolgen soll, indem die GetObjectToSerialize-Methode implementiert wird. Beispiel:
public object GetObjectToSerialize(object obj, Type targetType)
{
Console.WriteLine("GetObjectToSerialize");
if (obj is Inventory)
{
InventorySurrogated isur = new InventorySurrogated();
isur.numpaper = ((Inventory)obj).paper;
isur.numpencils = ((Inventory)obj).pencils;
isur.pens = ((Inventory)obj).pens;
return isur;
}
return obj;
}
Die GetObjectToSerialize Methode wird aufgerufen, wenn ein Objekt serialisiert wird. Diese Methode überträgt Daten vom ursprünglichen Typ an die Felder des ersatzierten Typs. Felder können direkt an Ersatzfelder zugeordnet werden, oder Manipulationen der Originaldaten können in den Ersatzfeldern gespeichert werden. Einige mögliche Verwendungsmöglichkeiten sind: direkte Zuordnung der Felder, Ausführen von Vorgängen für die Daten, die in den ersatzierten Feldern gespeichert werden sollen, oder das Speichern des XML-Codes des ursprünglichen Typs im ersatzierten Feld.
Der targetType Parameter bezieht sich auf den deklarierten Typ des Elements. Dieser Parameter ist der von der GetDataContractType Methode zurückgegebene Ersatztyp. Der Serialisierer erzwingt nicht, dass das zurückgegebene Objekt diesem Typ zugewiesen werden kann. Der obj Parameter ist das zu serialisierende Objekt und wird bei Bedarf in dessen Ersatz konvertiert. Diese Methode muss das Eingabeobjekt zurückgeben, wenn das Objekt nicht vom Surrogated verarbeitet wird. Andernfalls wird das neue Ersatzobjekt zurückgegeben. Der Ersatz wird nicht aufgerufen, wenn das Objekt null ist. Innerhalb dieser Methode werden möglicherweise zahlreiche Ersatzzeichenzuordnungen für verschiedene Instanzen definiert.
Beim Erstellen eines Objekts DataContractSerializerkönnen Sie sie anweisen, Objektverweise beizubehalten. (Weitere Informationen finden Sie unter Serialisierung und Deserialisierung.) Dies geschieht durch Festlegen des preserveObjectReferences Parameters im Konstruktor auf true. In diesem Fall wird der Ersatz nur einmal für ein Objekt aufgerufen, da alle nachfolgenden Serialisierungen einfach den Verweis in den Datenstrom schreiben. Wenn preserveObjectReferences auf false festgelegt ist, wird das Surrogat jedes Mal aufgerufen, wenn eine Instanz angetroffen wird.
Wenn sich der Typ der serialisierten Instanz vom deklarierten Typ unterscheidet, werden Die Typinformationen beispielsweise in den Datenstrom geschrieben, xsi:type damit die Instanz am anderen Ende deserialisiert werden kann. Dieser Vorgang tritt auf, unabhängig davon, ob das Objekt stellvertretend behandelt wird oder nicht.
Im obigen Beispiel werden die Daten der Inventory-Instanz in die InventorySurrogated-Instanz konvertiert. Er überprüft den Typ des Objekts und führt die erforderlichen Manipulationen aus, um in den ersatzierten Typ zu konvertieren. In diesem Fall werden die Felder der Inventory Klasse direkt in die InventorySurrogated Klassenfelder kopiert.
GetDeserializedObject-Methode
Die GetDeserializedObject Methode konvertiert die Instanz des ersatzierten Typs in die ursprüngliche Typinstanz. Sie ist für die Deserialisierung erforderlich.
Die nächste Aufgabe besteht darin, die Art und Weise zu definieren, wie die physischen Daten von der Ersatzinstanz dem Original zugeordnet werden. Beispiel:
public object GetDeserializedObject(object obj, Type targetType)
{
Console.WriteLine("GetDeserializedObject");
if (obj is InventorySurrogated)
{
Inventory invent = new Inventory();
invent.pens = ((InventorySurrogated)obj).pens;
invent.pencils = ((InventorySurrogated)obj).numpencils;
invent.paper = ((InventorySurrogated)obj).numpaper;
return invent;
}
return obj;
}
Diese Methode wird nur während der Deserialisierung eines Objekts aufgerufen. Sie sorgt für die umgekehrte Datenzuordnung für die Deserialisierung vom Ersatzzeichentyp zum ursprünglichen Typ. Ähnlich wie bei der GetObjectToSerialize Methode können einige mögliche Verwendungen sein, um Felddaten direkt auszutauschen, Vorgänge für die Daten auszuführen und XML-Daten zu speichern. Beim Deserialisieren erhalten Sie möglicherweise aufgrund von Manipulationen in der Datenkonvertierung nicht immer die genauen Datenwerte aus dem Original.
Der targetType Parameter bezieht sich auf den deklarierten Typ des Elements. Dieser Parameter ist der von der GetDataContractType Methode zurückgegebene Ersatztyp. Der obj Parameter bezieht sich auf das Objekt, das deserialisiert wurde. Das Objekt kann wieder in seinen ursprünglichen Typ konvertiert werden, wenn es überführt wird. Diese Methode gibt den Eingabeobjekttyp zurück, wenn das Ersatzzeichen das Objekt nicht behandelt. Andernfalls wird das deserialisierte Objekt zurückgegeben, nachdem die Konvertierung abgeschlossen wurde. Wenn mehrere Ersatztypen vorhanden sind, können Sie für jeden die Datenkonvertierung vom Ersatztyp zum primären Typ bereitstellen, indem Sie den jeweiligen Typ und dessen Konvertierung angeben.
Beim Zurückgeben eines Objekts werden die internen Objekttabellen mit dem von diesem Ersatz zurückgegebenen Objekt aktualisiert. Alle nachfolgenden Verweise auf eine Instanz erhalten die surrogatete Instanz aus den Objekttabellen.
Im vorherigen Beispiel werden Objekte vom Typ InventorySurrogated zurück in den ursprünglichen Typ Inventorykonvertiert. In diesem Fall werden die Daten direkt von InventorySurrogated auf seine entsprechenden Felder in Inventory zurückübertragen. Da keine Datenmanipulationen vorhanden sind, enthalten die einzelnen Memberfelder dieselben Werte wie vor der Serialisierung.
GetCustomDataToExport-Methode
Beim Exportieren eines Schemas ist die GetCustomDataToExport Methode optional. Es wird verwendet, um zusätzliche Daten oder Hinweise in das exportierte Schema einzufügen. Zusätzliche Daten können auf Elementebene oder Typebene eingefügt werden. Beispiel:
public object GetCustomDataToExport(System.Reflection.MemberInfo memberInfo, Type dataContractType)
{
Console.WriteLine("GetCustomDataToExport(Member)");
System.Reflection.FieldInfo fieldInfo = (System.Reflection.FieldInfo)memberInfo;
if (fieldInfo.IsPublic)
{
return "public";
}
else
{
return "private";
}
}
Diese Methode (mit zwei Überladungen) ermöglicht die Aufnahme zusätzlicher Informationen in die Metadaten entweder auf Element- oder Typebene. Es ist möglich, Hinweise darauf zu geben, ob ein Mitglied öffentlich oder privat ist, sowie Kommentare, die während des gesamten Exports und Imports des Schemas beibehalten werden. Solche Informationen würden ohne diese Methode verlorengehen. Diese Methode verursacht nicht das Einfügen oder Löschen von Elementen oder Typen, sondern fügt den Schemas auf einer dieser Ebenen zusätzliche Daten hinzu.
Die Methode wird überladen und kann entweder einen Type (clrtype Parameter) oder MemberInfo ( ParametermemberInfo ) verwenden. Der zweite Parameter ist immer ein Type ( ParameterdataContractType ). Diese Methode wird für jedes Element und jeden Typ des ersatzierten dataContractType Typs aufgerufen.
Eine dieser Überladungen muss entweder null oder ein serialisierbares Objekt zurückgeben. Ein Nicht-NULL-Objekt wird als Anmerkung in das exportierte Schema serialisiert. Bei der Type-Überladung wird jeder Typ, der in das Schema exportiert wird, im ersten Parameter zusammen mit dem Ersatzzeichentyp als der dataContractType-Parameter zu dieser Methode gesendet. Bei der MemberInfo-Überladung sendet jeder Member, der in das Schema exportiert wird, seine Informationen als den memberInfo-Parameter mit dem Ersatzzeichentyp im zweiten Parameter.
GetCustomDataToExport-Methode (Typ, Typ)
Die IDataContractSurrogate.GetCustomDataToExport(Type, Type) Methode wird während des Schemaexports für jede Typdefinition aufgerufen. Die Methode fügt beim Exportieren Informationen zu den Typen innerhalb des Schemas hinzu. Jeder definierte Typ wird an diese Methode gesendet, um zu bestimmen, ob zusätzliche Daten vorhanden sind, die im Schema enthalten sein müssen.
GetCustomDataToExport-Methode (MemberInfo, Typ)
Das IDataContractSurrogate.GetCustomDataToExport(MemberInfo, Type) wird während des Exports für jedes Mitglied in den exportierten Typen aufgerufen. Mit dieser Funktion können Sie alle Kommentare für die Elemente anpassen, die beim Export im Schema enthalten sein werden. Die Informationen für jedes Element innerhalb der Klasse werden an diese Methode gesendet, um zu überprüfen, ob zusätzliche Daten im Schema hinzugefügt werden müssen.
Das obige Beispiel durchsucht den dataContractType für jeden Member des Ersatzzeichens. Anschließend wird der entsprechende Zugriffsmodifizierer für jedes Feld zurückgegeben. Ohne diese Anpassung ist der Standardwert für Zugriffsmodifizierer öffentlich. Daher würden alle Member im Code als öffentlich definiert, der mit dem exportierten Schema generiert wurde, unabhängig davon, welche tatsächlichen Zugriffsbeschränkungen sie haben. Wenn diese Implementierung nicht verwendet wird, wäre das Element numpens im exportierten Schema öffentlich, obwohl es im Ersatz als privat definiert wurde. Durch die Verwendung dieser Methode kann im exportierten Schema der Zugriffsmodifizierer als privat generiert werden.
GetReferencedTypeOnImport-Methode
Diese Methode ordnet dem ursprünglichen Typ den Type des Ersatzzeichens zu. Diese Methode ist optional für den Schemaimport.
Beim Erstellen eines Ersatzs, der ein Schema importiert und Code dafür generiert, besteht die nächste Aufgabe darin, den Typ einer Ersatzinstanz für den ursprünglichen Typ zu definieren.
Wenn der generierte Code auf einen vorhandenen Benutzertyp verweisen muss, erfolgt dies durch Implementieren der GetReferencedTypeOnImport Methode.
Beim Importieren eines Schemas wird diese Methode für jede Typdeklaration aufgerufen, um den ersatzierten Datenvertrag einem Typ zuzuordnen. Die Zeichenfolgenparameter typeName und typeNamespace definieren den Namen und den Namespace des surrogateten Typs. Der Rückgabewert GetReferencedTypeOnImport wird verwendet, um zu bestimmen, ob ein neuer Typ generiert werden muss. Diese Methode muss entweder einen gültigen Typ oder null zurückgeben. Bei gültigen Typen wird der zurückgegebene Typ als referenzierter Typ im generierten Code verwendet. Wenn NULL zurückgegeben wird, wird kein Typ referenziert, und ein neuer Typ muss erstellt werden. Wenn mehrere Surrogate vorhanden sind, ist es möglich, die Zuordnung für jeden Ersatztyp zurück zum ursprünglichen Typ durchzuführen.
Der customData Parameter ist das Objekt, das ursprünglich von der GetCustomDataToExport zurückgegeben wurde. Dies customData wird verwendet, wenn Stellvertreterautoren zusätzliche Daten/Hinweise in die Metadaten einfügen möchten, die beim Import zum Generieren von Code verwendet werden sollen.
ProcessImportedType-Methode
Die ProcessImportedType Methode passt jeden Typ an, der aus dem Schemaimport erstellt wurde. Diese Methode ist optional.
Beim Importieren eines Schemas können mit dieser Methode alle importierten Typ- und Kompilierungsinformationen angepasst werden. Beispiel:
public System.CodeDom.CodeTypeDeclaration ProcessImportedType(System.CodeDom.CodeTypeDeclaration typeDeclaration, System.CodeDom.CodeCompileUnit compileUnit)
{
Console.WriteLine("ProcessImportedType");
foreach (CodeTypeMember member in typeDeclaration.Members)
{
object memberCustomData = member.UserData[typeof(IDataContractSurrogate)];
if (memberCustomData != null
&& memberCustomData is string
&& ((string)memberCustomData == "private"))
{
member.Attributes = ((member.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Private);
}
}
return typeDeclaration;
}
Während des Imports wird diese Methode für jeden generierten Typ aufgerufen. Ändern Sie die angegebene CodeTypeDeclaration oder ändern Sie die CodeCompileUnit. Zu diesen Veränderungen gehören das Ändern des Namens, der Mitglieder, der Attribute und vieler anderer Eigenschaften der CodeTypeDeclaration. Durch Verarbeiten der CodeCompileUnit ist es möglich, die Anweisungen, die Namespaces, die referenzierten Assemblys und verschiedene andere Aspekte zu ändern.
Der CodeTypeDeclaration Parameter enthält die DOM-Codetypdeklaration. Der CodeCompileUnit Parameter ermöglicht änderungen für die Verarbeitung des Codes. Das Zurückgeben von null-Ergebnissen führt dazu, dass die Typdeklaration verworfen wird. Umgekehrt werden beim Zurückgeben von CodeTypeDeclaration die Änderungen beibehalten.
Wenn benutzerdefinierte Daten während des Metadatenexports eingefügt werden, muss sie während des Imports dem Benutzer bereitgestellt werden, damit er verwendet werden kann. Diese benutzerdefinierten Daten können für Programmiermodellhinweise oder andere Kommentare verwendet werden. Jede Instanz von CodeTypeDeclaration und CodeTypeMember enthält benutzerdefinierte Daten als UserData-Eigenschaft, die in den IDataContractSurrogate-Typ gecastet werden.
Im obigen Beispiel werden einige Änderungen am importierten Schema ausgeführt. Der Code behält private Member des ursprünglichen Typs bei, indem ein Ersatzzeichen verwendet wird. Der Standardzugriffsmodifizierer beim Importieren eines Schemas ist public. Daher sind alle Mitglieder des Surrogat-Schemas öffentlich, sofern nicht geändert, wie in diesem Beispiel. Während des Exports werden benutzerdefinierte Daten in die Metadaten eingefügt, die Informationen darüber enthalten, welche Mitglieder privat sind. Im Beispiel werden die benutzerdefinierten Daten abgerufen, überprüft, ob der Zugriffsmodifizierer privat ist, und das entsprechende Mitglied wird geändert, indem seine Attribute auf privat gesetzt werden. Ohne diese Anpassung würde das numpens Mitglied als öffentlich und nicht als privat definiert.
GetKnownCustomDataTypes-Methode
Diese Methode ruft benutzerdefinierte Datentypen ab, die aus dem Schema definiert sind. Die Methode ist optional für den Schemaimport.
Die Methode wird am Anfang des Schemaexports und -imports aufgerufen. Die Methode gibt die benutzerdefinierten Datentypen zurück, die im Schema exportiert oder importiert werden. Der Methode wird ein Collection<T> (der customDataTypes-Parameter) übergeben, bei dem es sich um eine Sammlung von Typen handelt. Die Methode sollte dieser Auflistung weitere bekannte Typen hinzufügen. Die bekannten benutzerdefinierten Datentypen sind erforderlich, um mithilfe der DataContractSerializer benutzerdefinierte Daten zu serialisieren und deserialisieren. Weitere Informationen finden Sie unter Datenvertrag: Bekannte Typen.
Implementieren eines Ersatzzeichens
Um das Datenvertrags-Surrogate in WCF zu verwenden, müssen Sie einige spezielle Verfahren befolgen.
So verwenden Sie einen Surrogat für die Serialisierung und Deserialisierung
Verwenden Sie die DataContractSerializer, um die Serialisierung und Deserialisierung von Daten mit dem Surrogat durchzuführen. Das DataContractSerializer wird durch das DataContractSerializerOperationBehavior erstellt. Der Ersatz muss ebenfalls angegeben werden.
So implementieren Sie Serialisierung und Deserialisierung
Erstellen Sie eine Instanz für Ihren ServiceHost-Dienst. Vollständige Anweisungen finden Sie unter Grundlegende WCF-Programmierung.
Suchen Sie für jeden ServiceEndpoint des angegebenen Diensthosts seine OperationDescription.
Durchsuchen Sie das Vorgangsverhalten, um zu ermitteln, ob eine Instanz von DataContractSerializerOperationBehavior vorhanden ist.
Wenn ein DataContractSerializerOperationBehavior gefunden wird, legen Sie dessen DataContractSurrogate-Eigenschaft auf eine neue Instanz des Ersatzzeichens fest. Wenn kein DataContractSerializerOperationBehavior gefunden wird, dann erstellen Sie eine neue Instanz, und legen Sie den DataContractSurrogate-Member des neuen Verhaltens auf eine neue Instanz des Ersatzzeichens fest.
Fügen Sie schließlich dieses neue Verhalten zu den aktuellen Vorgangsverhalten hinzu, wie im folgenden Beispiel gezeigt:
using (ServiceHost serviceHost = new ServiceHost(typeof(InventoryCheck))) 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.DataContractSurrogate = new InventorySurrogated(); } else { dataContractBehavior = new DataContractSerializerOperationBehavior(op); dataContractBehavior.DataContractSurrogate = new InventorySurrogated(); op.Behaviors.Add(dataContractBehavior); } } }
So verwenden Sie einen Ersatz für den Metadatenimport
Beim Importieren von Metadaten wie WSDL und XSD zur Generierung von clientseitigem Code muss das Surrogat zu der Komponente hinzugefügt werden, die für die Generierung von Code aus dem XSD-Schema XsdDataContractImporter verantwortlich ist. Um dies zu tun, ändern Sie das WsdlImporter, das zum Importieren von Metadaten verwendet wird, direkt.
Um einen Stellvertreter für den Metadatenimport einzurichten
Importieren Sie die Metadaten mithilfe der WsdlImporter Klasse.
Verwenden Sie die TryGetValue Methode, um zu überprüfen, ob eine XsdDataContractImporter definiert wurde.
Wenn die TryGetValue Methode
falsezurückgibt, erstellen Sie eine neue XsdDataContractImporter und legen Sie ihre Options-Eigenschaft auf eine neue Instanz der ImportOptions-Klasse fest. Verwenden Sie andernfalls den von demoutParameter der TryGetValue Methode zurückgegebenen Importer.Wenn für den XsdDataContractImporter keine ImportOptions definiert sind, dann legen Sie die Eigenschaft auf eine neue Instanz der ImportOptions-Klasse fest.
Legen Sie die DataContractSurrogate-Eigenschaft der ImportOptions des XsdDataContractImporter auf eine neue Instanz des Ersatzzeichens fest.
Fügen Sie den XsdDataContractImporter der Sammlung hinzu, die durch die State-Eigenschaft des WsdlImporter (geerbt von der MetadataExporter-Klasse) zurückgegeben wird.
Verwenden Sie die Methode ImportAllContracts des WsdlImporter, um alle Datenverträge innerhalb des Schemas zu importieren. Während des letzten Schritts wird Code aus den geladenen Schemas durch Aufruf in das Ersatzzeichen generiert.
MetadataExchangeClient mexClient = new MetadataExchangeClient(metadataAddress); mexClient.ResolveMetadataReferences = true; MetadataSet metaDocs = mexClient.GetMetadata(); WsdlImporter importer = new WsdlImporter(metaDocs); object dataContractImporter; XsdDataContractImporter xsdInventoryImporter; if (!importer.State.TryGetValue(typeof(XsdDataContractImporter), out dataContractImporter)) xsdInventoryImporter = new XsdDataContractImporter(); xsdInventoryImporter = (XsdDataContractImporter)dataContractImporter; xsdInventoryImporter.Options ??= new ImportOptions(); xsdInventoryImporter.Options.DataContractSurrogate = new InventorySurrogated(); importer.State.Add(typeof(XsdDataContractImporter), xsdInventoryImporter); Collection<ContractDescription> contracts = importer.ImportAllContracts();
So verwenden Sie einen Stellvertreter für den Metadatenexport
Standardmäßig muss beim Exportieren von Metadaten aus WCF für einen Dienst sowohl das WSDL- als auch das XSD-Schema generiert werden. Der Stellvertreter muss der Komponente hinzugefügt werden, die verantwortlich ist für das Generieren des XSD-Schemas für Datenvertragstypen XsdDataContractExporter. Verwenden Sie dazu entweder ein Verhalten, das IWsdlExportExtension implementiert, um WsdlExporter zu ändern, oder ändern Sie direkt die WsdlExporter, die verwendet werden, um Metadaten zu exportieren.
So verwenden Sie ein Ersatzzeichen für den Metadatenexport
Erstellen Sie einen neuen WsdlExporter Parameter, oder verwenden Sie den
wsdlExporterParameter, der an die ExportContract Methode übergeben wird.Verwenden Sie die TryGetValue Funktion, um zu überprüfen, ob eine XsdDataContractExporter definiert wurde.
Wenn TryGetValue
falsezurückgibt, erstellen Sie ein neues XsdDataContractExporter mit den generierten XML-Schemata aus WsdlExporter und fügen Sie es der Sammlung hinzu, die von der State-Eigenschaft des WsdlExporter zurückgegeben wird. Verwenden Sie andernfalls das Exportprogramm, das durch denout-Parameter der TryGetValue-Methode zurückgegeben wird.Wenn für die XsdDataContractExporter kein ExportOptions definiert ist, legen Sie die Options Eigenschaft auf eine neue Instanz der Klasse ExportOptions fest.
Legen Sie die DataContractSurrogate-Eigenschaft der ExportOptions des XsdDataContractExporter auf eine neue Instanz des Ersatzzeichens fest. In den nachfolgenden Schritten zum Exportieren von Metadaten sind keine Änderungen erforderlich.
WsdlExporter exporter = new WsdlExporter(); //or //public void ExportContract(WsdlExporter exporter, // WsdlContractConversionContext context) { ... } object dataContractExporter; XsdDataContractExporter xsdInventoryExporter; if (!exporter.State.TryGetValue(typeof(XsdDataContractExporter), out dataContractExporter)) { xsdInventoryExporter = new XsdDataContractExporter(exporter.GeneratedXmlSchemas); } else { xsdInventoryExporter = (XsdDataContractExporter)dataContractExporter; } exporter.State.Add(typeof(XsdDataContractExporter), xsdInventoryExporter); if (xsdInventoryExporter.Options == null) xsdInventoryExporter.Options = new ExportOptions(); xsdInventoryExporter.Options.DataContractSurrogate = new InventorySurrogated();