2009-06-01 13 views
10

¿Cómo puedo definir un método [OperationContract] [WebGet] para devolver XML que está almacenado en una cadena, sin que HTML codifique la cadena?Cómo se emite XML desnudo para un método [WebGet] en WCF?

La aplicación está utilizando el servicio WCF para devolver contenido XML/XHTML que se ha almacenado como una cadena. El XML no se corresponde con ninguna clase específica a través de [DataContract]. Está destinado a ser consumido por un XSLT.

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

que tienen esta clase:

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

Pero cuando serializado, hay una etiqueta raíz de las envolturas del contenido dado.

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

sé cómo cambiar el nombre de la etiqueta raíz ([XmlRoot (ElementName = "div")]), pero tengo que omitir la etiqueta raíz, si es posible.

También he intentado [DataContract] en lugar de IXmlSerializable, pero parece menos flexible.

Respuesta

8

Devuelve un XmlElement. No necesita IXmlSerializable. No necesitas una clase de contenedor.

ejemplo de interfaz de servicio: aplicación

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

servicio:

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

Véase también, esta pregunta similar, pero sin el toque WebGet:
serializing-generic-xml-data-across-wcf-web-service-requests.

+0

Gracias! Eso funciona, pero tiene el inconveniente de deserializar el XML y luego volver a serializarlo. No es tan eficiente como me gustaría, pero al menos elimina la etiqueta raíz. Gracias por la alternativa. –

+0

Sí, creo que si sus datos originales están almacenados como una cadena, debe pasar por ese proceso de varios pasos. Si solo se trata de cadenas estáticas, puede desactivarlo solo una vez y luego almacenar en caché el resultado. Supongamos que es una plantilla que completa para el fragmento de documento final: puede almacenar en caché la plantilla y completar los bits dinámicos con cada solicitud. – Cheeso

+0

usando este ejemplo con lanzamientos mono 2.10.8.1 - El tipo de excepción 'System.Xml.XmlElement' no puede tener un atributo de DataContract Nombre establecido en una cadena vacía o nula. – Tom

Cuestiones relacionadas