Ignorieren Sie dynamisch, dass Datenelemente serialisiert werden

8

Wir haben einen bestehenden WCF-Dienst, der mehrere DataContracts verwendet. Wir möchten die Serialisierung basierend auf dem Gerät ändern, so dass der Dienst bei Zugriff von mobilen Geräten nur einige wichtige Datenelemente (nicht alle) serialisieren sollte

Wir haben hier 2 Möglichkeiten

  1. Erstellen Sie separate Betriebs- und Datenverträge für verschiedene Arten von Geräte
  2. Verwechseln Sie die tatsächliche XML-Serialisierung und unterdrücken Sie das Erstellen unnötige Elemente basierend auf dem Gerät

Wir wollen nicht mit der ersten Option gehen, da es in Zukunft viele redundante Code-Probleme einführt

Kleine Untersuchungen haben gezeigt, dass wir IXmlSerializable verwenden und die readXML () und writeXML () Methoden überschreiben müssen. Aber zur gleichen Zeit habe ich irgendwo gesehen, dass DataContract und IXmlSerializable nicht zusammen verwendet werden sollten

Jedes Beispiel, das mit der tatsächlichen Serialisierung in Konflikt gerät, wird sehr geschätzt.

%Vor%

Wenn ich nun auf den Dienst zugreife, der einen typischen TokenMessage-Datenvertrag von einem mobilen Gerät zurückgibt, möchte ich nicht, dass der Datenelement "Extra" serialisiert wird, dh wenn ich dem Vorgangsvertrag ein anderes Argument gebe in der Lage sein, einige / alle Datenelemente (abhängig von der Aktion) zu serialisieren

PS: Bitte ignorieren Sie zunächst den Geräteerkennungsteil. Nehmen wir an, wir haben ein Argument im Operationsvertrag, das uns hilft, das Gerät zu identifizieren

    
Surya KLSV 13.01.2014, 12:51
quelle

4 Antworten

3

Ich bin nicht davon überzeugt, dass eine Variante von @Pranav Singhs Antwort kein besseres Design ist, aber das ist nicht deine Frage ...

Wie Sie in einem Kommentar erwähnt haben, sind Attribute in .NET statisch. Das bedeutet, das Hinzufügen / Entfernen von [DataMember] ist keine gute Option. Es ist möglich. Es gibt Optionen wie die Verwendung von Reflection.Emit, um die Instanz mit den Metadatenänderungen neu zu erstellen (siehe alle Antworten zu Können Attribute dynamisch in C # hinzugefügt werden? ), aber alle diese Routen sind kompliziert.

Ich sehe zwei sinnvolle Optionen:

1) Implementieren Sie einen IParameterInspector für den Service . In der AfterCall () Methode können Sie die Parameter werden an den Client zurückgegeben, bevor sie serialisiert werden . Es gibt einige Arbeiten, die Reflektion verwenden, um die Parametertypen dynamisch zu bestimmen und ihre Werte festzulegen, aber es ist nicht kompliziert. Dies ist das bessere Design, das die Wiederverwendung des Verhaltens über viele Verträge oder Dienste hinweg ermöglicht. Carlos Figueiras Blog ist die beste Quelle für die WCF-Erweiterung Beispiele.

2) Verwenden Sie die [OnSerializing] und [OnSerialized] Ereignisse. In [DataContract] konnten Sie vorübergehend ändern, was die Eigenschaften während der Serialisierung zurückgeben. Die Ereignisse sind eigentlich entworfen, um die Initialisierung zu ermöglichen und als solche ist diese Lösung ein bisschen wie ein Hack . Diese Lösung ist auch nicht threadsicher. Aber es hält den enthaltenen Code in der DataContract-Klasse und löst das Problem schnell (und ich denke, dass Sie schnell suchen).

Lösung # 2 könnte etwa so aussehen:

%Vor%

Lösung # 2 ist eine schnelle Lösung (was ich denke, dass Sie suchen).

Lösung # 1 ist das bessere Design.

    
ErnieL 15.01.2014 18:09
quelle
1

Es gibt einen Ansatz, aber ich denke, dass dies die Generierung eines zusätzlichen DataContract erfordert, aber noch keine separaten Betriebs- und Datenverträge für verschiedene Gerätetypen. Es kann klassische Implementierung zu Laufzeitpolymorphismus sein. Ich gebe nur eine Idee:

Angenommen, Sie haben einen generischen DataContract wie:

%Vor%

Andere gerätespezifische Verträge können TokenMessage als Basisklasse erben:

%Vor%

Jetzt zur Laufzeit wie Sie sagen, dass Sie ein Argument im Operationsvertrag kennen, das uns hilft, das Gerät zu identifizieren. Sagen Sie basierend auf dem Gerätetyp, dass Sie die Basisklasse mit abgeleiteten Klassen wie:

instanziieren können %Vor%

ODER

%Vor%

Sie werden also zur Laufzeit entscheiden, welcher Gerätevertrag Teil der generischen Antwort sein soll.

Hinweis: Durch das Hinzufügen von KnownType wird das separate xsd innerhalb von wsdl für alle bekannten Typen in der Basisklasse generiert, die Serialisierung für Daten wird jedoch zur Laufzeit gespeichert, da dies von der gewählten Vererbung abhängen sollte.

    
Pranav Singh 14.01.2014 11:52
quelle
0

Versuchen Sie es mit IgnoreDataMemberAttribute

    
PushCode 13.01.2014 20:03
quelle
-2

Fügen Sie in Ihrem Modell eine Eigenschaft 'ShouldSerializeYOUR_PROPERTY_NAME' hinzu und setzen Sie sie auf 'false', wenn die Eigenschaft serialisiert werden soll. Weitere Informationen finden Sie hier: Ссылка

    
lcryder 13.01.2014 13:29
quelle

Tags und Links