使用WCF输出XHTML的最佳/最灵活的方法是什么?

时间:2009-02-17 20:12:28

标签: .net wcf web-services rest

使用WCF输出XHTML的最佳/最灵活的方法是什么?如果没有“WCF Way”(tm)来做XHTML输出 - 那么有没有常见的工具呢?或者我需要自己动手吗?

3 个答案:

答案 0 :(得分:2)

WCF关注数据传输。它允许您为客户端/主机设置服务合同以进行通信。它抽象了您的传输,以便您可以轻松配置您的服务,无论是通过HTTP / TCP / NamedPipes / Tibco EMS /您想要什么。根据我的经验,通过线路本身的消息默认都被序列化为SOAP,但这当然也是可配置的。 XHTML是演示文稿(是的,你可以说CSS是真正的演示文稿而XHTML是你的数据表示)。您基本上希望以一种可以通过Web浏览器呈现的方式返回您的数据。

这对我没有意义的原因是你似乎试图在Web服务器所属的地方放置一个WCF服务。

但是让我们看看它是如何完成的:

您是否希望WCF基础架构通过网络将消息实际格式化为XHTML?如果是,并且您想要向服务发送REST样式请求,请从WCF REST Starter Kit开始。

主要挑战是序列化。我知道.Net 3.5 SP1中的WCF允许用户使用JsonDataContractSerializer运行WCF,而不是将对象序列化为XML的标准DataContractSerializer。你可以编写自己的XHTMLDataContractSerializer。但是,由此产生的XHTML将是您自己的。 Here's一个让你开始的线程。

编辑:刚刚找到this。我认为这绝对是一种选择。它似乎很容易实现。

答案 1 :(得分:1)

WCF是一种组件技术 - 您编写接口及其实现,然后指示WCF如何处理安全性,传输等。

从WCF组件返回XHTML与从任何其他.NET组件返回WCF相同 - 可能是作为字符串。只要您可以通过基本类型或通过有效的数据合同从组件中返回数据,您就应该很酷。

您可能需要查看Juval Lowy编程WCF服务的第3章 - 这些都是关于数据合同以及您可以从组件中吐出的所有内容。也许你正在寻找一些neato方法来在客户从组件中取回一些东西后反序列化数据......如果是这样,Lowy会告诉你如何。

因此,简短的回答是从您的组件返回XHTML,但是您需要。据我所知,没有特殊的方法从WCF组件发出XHTML。

答案 2 :(得分:1)

从.NET 3.5 SP1开始,我不相信有一种“官方”WCF方式可以返回XHTML。 Aaron Lerch suggested having WCF apply a default XSLT stylesheet in July 2007,但WCF团队尚未采用此类内容。

正如其他答案所述,您可以使用WCF Starter Kitraw programming model described by Carlos Figueira中的示例推广自己的XHTML支持。 Michele Leroux Bustamante在线提供的一些WCF sample code作为她Learning WCF书籍的一部分,如果您决定自己这样做,将会很有帮助。

我们从基于WCF的Web服务返回XHTML以及JSON和XML。虽然我不确定我们的方法是最佳方式,但确实有效。

我们的方法是使用DataContractSerializer生成XML,然后应用Complied XSLT转换并返回结果流,现在应该包含XHTML。这是我们代码的简化版本:

public Stream GetItemAsHtml(string id) {
    Item obj = GetItem(objectId);
    Stream xml = GetXmlStream(obj);    
    return TransformXmlStream(xml, defaultTransform);
}        

public static Stream GetXmlStream(IXmlSerializable item) {
    MemoryStream stream = new MemoryStream();
    using (XmlWriter writer = XmlWriter.Create(stream, new XmlWriterSettings { Encoding = Encoding.UTF8 })) {
        if (writer != null) {
            DataContractSerializer dcs = new DataContractSerializer(item.GetType());
            dcs.WriteObject(writer, item);

            writer.Flush();
            writer.Close();
        }
    }
    stream.Seek(0, SeekOrigin.Begin);
    return stream;
}

public static Stream TransformXmlStream(Stream xml, string xsltFile) {
    XmlReader reader = XmlReader.Create(xml);

    XslCompiledTransform trans = new XslCompiledTransform();
    trans.Load(xsltFile);

    MemoryStream stream = new MemoryStream();
    using (XmlWriter writer = XmlWriter.Create(stream, trans.OutputSettings)) {
        if (writer != null) {
            trans.Transform(reader, writer);

            writer.Flush();
            writer.Close();
        }
    }
    stream.Seek(0, SeekOrigin.Begin);
    return stream;
}

它完成了这项工作,但我不认为这是WCF设计师预期的一种情况。 :-)