2009-06-01 1 views
10

Wie kann ich eine Methode [OperationContract] [WebGet] definieren, um XML zurückzugeben, das in einer Zeichenfolge gespeichert ist, ohne dass HTML die Zeichenfolge codiert?Wie Embedded XML für eine [WebGet] -Methode in WCF?

Die Anwendung verwendet den WCF-Dienst zum Zurückgeben von XML/XHTML-Inhalt, der als Zeichenfolge gespeichert wurde. Das XML entspricht keiner bestimmten Klasse über [DataContract]. Es soll von einem XSLT konsumiert werden.

[OperationContract] 
[WebGet] 
public XmlContent GetContent() 
{ 
    return new XmlContent("<p>given content</p>"); 
} 

Ich habe diese Klasse:

[XmlRoot] 
public class XmlContent : IXmlSerializable 
{ 
    public XmlContent(string content) 
    { 
     this.Content = content; 
    } 
    public string Content { get; set; } 

    #region IXmlSerializable Members 

    public System.Xml.Schema.XmlSchema GetSchema() 
    { 
     return null; 
    } 

    public void ReadXml(XmlReader reader) 
    { 
     throw new NotImplementedException(); 
    } 

    public void WriteXml(XmlWriter writer) 
    { 

     writer.WriteRaw(this.Content); 
    } 
    #endregion 
} 

Aber wenn serialisierte gibt es ein Root-Tag die Packungen der angegebenen Inhalt.

<XmlContent> 
    <p>given content</p> 
</XmlContent> 

Ich weiß, wie der Namen des Root-Tages ändern ([XmlRoot (Elementname = "div")]), aber ich brauche den Root-Tag, wenn überhaupt möglich zu verzichten.

Ich habe auch [DataContract] anstelle von IXmlSerializable versucht, aber es scheint weniger flexibel.

Antwort

8

Geben Sie ein XmlElement zurück. Sie benötigen IXmlSerializable nicht. Sie benötigen keine Wrapper-Klasse.

Beispiel Service-Schnittstelle:

namespace Cheeso.Samples.Webservices._2009Jun01 
{ 
    [ServiceContract(Namespace="urn:Cheeso.Samples.Webservices")] 
    public interface IWebGetService 
    { 
     [OperationContract] 
     [WebGet(
       BodyStyle = WebMessageBodyStyle.Bare, 
        RequestFormat = WebMessageFormat.Xml, 
        ResponseFormat = WebMessageFormat.Xml, 
        UriTemplate = "/Greet/{greeting}")] 
     XmlElement Greet(String greeting); 
    } 
} 

Service-Implementierung:

namespace Cheeso.Samples.Webservices._2009Jun01 
{ 
    [ServiceBehavior(Name="WcfWebGetService", 
        Namespace="urn:Cheeso.Samples.WebServices", 
        IncludeExceptionDetailInFaults=true)] 

    public class WcfWebGetService : IWebGetService 
    { 
     public XmlElement Greet (String greeting) 
     { 
      string rawXml = "<p>Stuff here</p>"; 
      XmlDocument doc = new XmlDocument(); 
      doc.Load(new System.IO.StringReader(rawXml)); 
      return doc.DocumentElement; 
     } 
    } 
} 

Siehe auch diese ähnliche Frage, aber ohne den WebGet Twist:
serializing-generic-xml-data-across-wcf-web-service-requests.

+0

Danke! Das funktioniert, hat aber den Nachteil, dass das XML deserialisiert und dann erneut serialisiert wird. Nicht so effizient, wie ich es möchte, aber zumindest eliminiert es das Root-Tag. Danke für die Alternative. –

+0

Yup, ich denke, wenn Ihre ursprünglichen Daten als eine Zeichenfolge gespeichert sind, müssen Sie diesen mehrstufigen Prozess durchlaufen. Wenn es sich nur um statische Strings handelt, können Sie nur einmal de-serieren und dann das Ergebnis zwischenspeichern. Angenommen, es handelt sich um eine Vorlage, die Sie für das endgültige Dokumentfragment ausfüllen. Sie könnten die Vorlage zwischenspeichern und die dynamischen Bits bei jeder Anforderung ausfüllen. – Cheeso

+0

Verwenden dieses Beispiels mit Mono 2.10.8.1-Würfen - Der Ausnahmetyp 'System.Xml.XmlElement' kann kein DataContract-Attribut Name auf null oder eine leere Zeichenfolge festlegen. – Tom