7 Stimmen

Mehrere Antworten von WCF zurückgeben

Ich habe einen WCF-Dienst und eine einzelne Methode namens GetStudentList() im Dienst, die gut funktioniert, wenn sie eine einzelne Antwort zurückgibt, etwa so

  [WebGet(ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
List<Student> GetStudentList();

Aber ich möchte mehrere Antwort d.h. xml und json both.something wie diese zurückgeben

  [WebGet(ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
[WebGet(ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
List<Student> GetStudentList();

Ist das möglich? Wenn ja, wie?

19voto

Ladislav Mrnka Punkte 355028

Das ist in .NET 4.0 möglich, aber nicht so, wie Sie es beschrieben haben. .NET 4.0 fügt neue Parameter zum WebHttp-Verhalten hinzu:

  <endpointBehaviors>
    <behavior name="WebHttp">
      <webHttp automaticFormatSelectionEnabled="true" />
    </behavior>
  </endpointBehaviors>

Wenn Sie die automatische Formatauswahl verwenden, basiert das Format der Antwort auf:

  • Accept-Header der Anfrage
  • Inhaltstyp der Anfrage
  • Standardformat, das beim Vorgang angegeben wird
  • Im webHttp-Verhalten festgelegtes Standardformat

Wenn Sie also Ihren REST-Dienst mit einer JSON-Anfrage aufrufen, erhalten Sie JSON. Wenn Sie ihn mit einer POX-Anfrage aufrufen, erhalten Sie XML. Eine vollständige Beschreibung der automatischen Formatauswahl finden Sie in MSDN .

3voto

KeithS Punkte 67713

Ich glaube nicht, dass es möglich ist, das Objekt sowohl als Json als auch als XML mit einem Aufruf zurückzugeben. Stellen Sie sich WCF in dieser Hinsicht wie einen normalen Methodenaufruf vor: Sie rufen eine Methode auf, Sie erhalten einen serialisierten Rückgabewert. Sobald der Dienst eine Antwort an den Aufrufer zurückgegeben hat, ist der Aufruf abgeschlossen.

Denken Sie sorgfältig darüber nach, warum Sie beide Antworttypen verwenden wollen; beide sind aussagekräftige, universelle Standards für die Objektserialisierung, und bei der Verwendung von WCF würden Sie beide nur benötigen, wenn Sie den serialisierten Antworttext direkt verwenden würden. Wenn irgend möglich, würde ich die Clients so umgestalten, dass sie mit demselben Antworttyp arbeiten.

Die einfachste Lösung, wenn wirklich zwei Typen benötigt werden, wäre es, zwei "Überladungen" dieser Methode bereitzustellen und jeden Client-Typ so intelligent zu machen, dass er weiß, welchen Aufruf er machen muss. Da der Unterschied nicht in der Methodensignatur liegt, handelt es sich nicht um eine echte Überladung; Sie müssen sie entweder durch den Namen (GetStudentListJSON vs. GetStudentListXML) oder durch die Unterbringung der Methoden in verschiedenen Serviceklassen trennen.

Sie könnten auch immer einen Antworttyp zurückgeben und auf der Client-Seite durch Deserialisierung/Reserialisierung konvertieren, wenn Sie das Objekt im anderen Format serialisiert benötigen. Dazu müssen Sie jedoch .NET-Code verwenden, den Sie auf der Client-Seite des Aufrufs kontrollieren können.

1voto

Josh Punkte 501

Ich kenne keine Möglichkeit, wie Sie 2 Ausgaben von einem Dienstvorgang erhalten können. Sie können immer die XML (serialisierte DataContract) erhalten und dann "JSON Serialize" es. Hier ist, wie Sie es tun können.

List<Student> studentList = GetStudent();
string jsonString = JsonSerialize(studentList.GetType(), studentList);

Und fügen Sie diese Funktion dann einer Utility-Klasse hinzu:

public static string JsonSerialize(Type type, object objectGraph)
        {
            MemoryStream memoryStream = new MemoryStream();

            try
            {
                System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(type);
                serializer.WriteObject(memoryStream, objectGraph);
                return Encoding.Default.GetString(memoryStream.ToArray());
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (memoryStream != null) memoryStream.Close();
            }
        }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X