2009-06-01 3 views
10

Come definire un metodo [OperationContract] [WebGet] per restituire l'XML memorizzato in una stringa, senza codificare HTML la stringa?Come emettere un XML puro per un metodo [WebGet] in WCF?

L'applicazione sta utilizzando il servizio WCF per restituire il contenuto XML/XHTML che è stato memorizzato come stringa. L'XML non corrisponde ad alcuna classe specifica tramite [DataContract]. È pensato per essere consumato da un XSLT.

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

ho questa classe:

[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 
} 

Ma quando serializzato, v'è un tag radice l'avvolge il contenuto attribuito.

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

so come cambiare il nome della tag root ([XmlRoot (ElementName = "div")]), ma ho bisogno di omettere il tag root, se possibile.

Ho anche provato [DataContract] invece di IXmlSerializable, ma sembra meno flessibile.

risposta

8

Restituisce un XmlElement. Non hai bisogno di IXmlSerializable. Non hai bisogno di una lezione di wrapper.

interfaccia esempio di servizio: implementazione

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); 
    } 
} 

servizio:

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; 
     } 
    } 
} 

Vedi anche, questa domanda simile, ma senza la torsione WebGet:
serializing-generic-xml-data-across-wcf-web-service-requests.

+0

Grazie! Funziona, ma ha lo svantaggio di deserializzare l'XML e quindi di ri-serializzarlo. Non efficiente come vorrei, ma almeno elimina il tag radice. Grazie per l'alternativa. –

+0

Sì, penso che se i tuoi dati originali sono memorizzati come una stringa, devi passare attraverso questa procedura multi-step. Se si tratta solo di stringhe statiche, è possibile de-ser una sola volta e quindi memorizzare nella cache il risultato. Supponendo che sia un modello da compilare per il frammento finale del documento: è possibile memorizzare nella cache il modello e inserire i bit dinamici a ogni richiesta. – Cheeso

+0

utilizzando questo esempio con versioni mono 2.10.8.1 - Tipo di eccezione "System.Xml.XmlElement" non può avere un attributo DataContract Nome impostato su null o stringa vuota. – Tom