2009-01-14 6 views
6

Ich habe einen C# WCF REST-Dienst, der das Hinzufügen eines Lesezeichens ermöglicht, indem eine HTTP-POST-Anforderung mit dem in XML serialisierten Lesezeichen gesendet wird. Ich habe den Vorgangsvertrag für den Dienst angegeben, der die XML-Datei abruft und das Objekt automatisch für mich deserialisiert. Mein Problem ist, dass die Deserialisierung nur funktioniert, wenn die XML-Elemente in der Anfrage in alphabetischer Reihenfolge angegeben sind und die Werte für alle Elemente, die nicht in der richtigen Reihenfolge sind, nicht aufgefüllt sind.Können WCF-REST-Services die Deserialisierung von XML-Nachrichten mit beliebiger Elementreihenfolge unterstützen?

This behaviour has been reported elsewhere.

Ich finde das ziemlich unbefriedigend; Ich halte die Anforderung, das XML in einer bestimmten Reihenfolge zu konstruieren, für unnötig und große Kopfschmerzen. Dies ist eine wichtige Anforderung, die allen Clients des Dienstes hinzugefügt werden muss, sowie eine Quelle potenziell schwieriger Debugprobleme.

Ist es möglich, WCF an XML-Element-Reihenfolge Agnostiker zu richten?


Einige weitere Details zum Zwecke Klarstellung:

sieht Mein Betrieb Vertrag wie folgt aus:

[OperationContract] 
[WebInvoke(Method="POST", UriTemplate = "/{username}/bookmarks", ResponseFormat = WebMessageFormat.Xml)] 
public void PostBookmark(string username, RestBookmark newBookmark); 

Die RestMessage wie folgt aussieht:

[DataContract(Name = "Bookmark", Namespace = "")] 
public class RestBookmark 
{ 
    [DataMember] 
    public string BookmarkMd5 { get; set; } 

    [DataMember] 
    public string Url { get; set; } 

    [DataMember] 
    public string UserName { get; set; } 

    [DataMember] 
    public string Title { get; set; } 

    [DataMember] 
    public string Description { get; set; } 
} 

Wenn ich die folgende XML-Nachricht zu senden, dann wird nur die Username-Eigenschaft des RestMessage Objekt wird aufgefüllt, wenn PostBookmark() aufgerufen wird:

<?xml version="1.0"?><Bookmark><UserName>nick.street</UserName><Url>http://www.stackoverflow.com</Url><BookmarkMd5>f184eb3347cf94f6ce5f5fc2844e3bdd</BookmarkMd5><Description>Developer Forum</Description><Title>Stack Overflow</Title></Bookmark> 

Antwort

1

Der DataContractSerializer erfordert eine strikte Anordnung der Elemente sowohl für die Versionierung als auch für die Leistung.

Es gibt einige Optionen, die ich denken kann,

  1. eine Nachricht schreiben Inspektor die rohen XML-Elemente in AfterReceivedRequest neu zu ordnen, bevor es deserialisiert von DataContractSerializer.

  2. mit dem XmlSerializer für Ihre Dienste.

  3. entwickeln HTTP-Raw-XML-Nachricht Prozess Service statt.

  4. passieren das Objekt als ein Wörterbuch (nicht empfohlen)

+0

Ich mag die Idee, den XMLSerializer zu verwenden. –

+0

Danke für die Hilfe und klare Antwort! –

-1

Versuchen Sie, die Bestellung auf 0 in der Datamember-Attribut-Einstellung (für alle Mitglieder) :

[Datamember (Name = "Title", Order = 0)]

+0

Danke für den Vorschlag. Es hat leider nicht geholfen - es scheint, dass wenn mehrere Artikel die gleiche Reihenfolge haben, sie wieder in alphabetischer Reihenfolge erscheinen, anstatt "ungeordnet". –

0

ich habe dies selbst nicht versucht zu tun, aber ich werde eine Vermutung nehmen.

Wäre es hilfreich, ein Ereignis [OnDeserializing] auf Ihrem DataContract zu erstellen, das kurz vor der Deserialisierung ausgelöst wird? An diesem Punkt könnten Sie vielleicht das XML neu anordnen, aber es muss geordnet werden, damit die Deserialisierung ordnungsgemäß funktioniert.

Wenn Sie Juval Lowy der Programmierung WCF Dienste 2nd Edition haben, dass abgedeckt wird ab Seite 107.

Here's the MSDN help page.

+0

Nun, je mehr ich es betrachte, bin ich mir nicht sicher, dass Sie zu diesem Zeitpunkt an die übergebene XML gelangen können, aber vielleicht können Sie den Haken irgendwie verwenden ... –

0

Wenn Sie nicht Order in Ihrem DataMember Attribut angeben, werden die Reihenfolge der Knoten zu reflektieren, dann müssen Sie die Knoten in Ihrem alphabetize XML.

Verwandte Themen