Asp.net 典型网站上的实时输出流。如果你是amazon.com之类的,当然是YMMV

Asp.net 典型网站上的实时输出流。如果你是amazon.com之类的,当然是YMMV,asp.net,xml-parsing,webforms,html-parsing,csquery,Asp.net,Xml Parsing,Webforms,Html Parsing,Csquery,我开发它的最初目的是从内容管理系统中操作HTML。一旦我安装并运行了它,我发现使用CSS选择器和jQueryAPI比使用web控件要有趣得多,于是开始将它用作服务器呈现页面的主要HTML操作工具,并将其构建成几乎涵盖所有CSS、jQuery和浏览器DOM。从那以后,我再也没有接触过web控件 要使用CsQuery截取webforms中的HTML,请在页面代码隐藏中执行此操作: using CsQuery; using CsQuery.Web; protected override void R

我开发它的最初目的是从内容管理系统中操作HTML。一旦我安装并运行了它,我发现使用CSS选择器和jQueryAPI比使用web控件要有趣得多,于是开始将它用作服务器呈现页面的主要HTML操作工具,并将其构建成几乎涵盖所有CSS、jQuery和浏览器DOM。从那以后,我再也没有接触过web控件

要使用CsQuery截取webforms中的HTML,请在页面代码隐藏中执行此操作:

using CsQuery;
using CsQuery.Web;

protected override void Render(HtmlTextWriter writer)
{

    var csqContext = WebForms.CreateFromRender(Page, base.Render, writer);

    // CQ object is like a jQuery object. The "Dom" property of the context
    // returned above represents the output of this page.

    CQ doc = csqContext.Dom;

    doc["li > a"].AddClass("foo");

    // write it
    csqContext.Render();
}
要在ASP.NET MVC中执行相同的操作,请参见描述

GitHub上有CsQuery的基本文档。除了输入和输出HTML之外,它的工作原理与jQuery非常相似。上面的
WebForms
对象只是为了帮助您处理与
htmltexwriter
对象和
Render
方法的交互。通用用途非常简单:

var doc = CQ.Create(htmlString);

// or (useful for scraping and testing)
var doc = CQ.CreateFromUrl(url);

// do stuff with doc, a CQ object that acts like a jQuery object

doc["table tr:first"].Append("<td>A new cell</td>");
当然,在C#中,您可以使用大量其他通用工具,如LINQ。或者:

var element = dom["div > input[type=checkbox]:first-child"].Single();

a.Checked=true; 
当您完成对文档的操作后,您可能希望将HTML输出:

string html = doc.Render();
就这些。在
CQ
对象上有大量方法,涵盖了所有jquerydom操作技术。还有处理JSON的实用方法,它广泛支持动态和匿名类型,使传递数据结构(例如,一组CSS类)尽可能容易,就像jQuery一样

一些更高级的东西

我不建议您这样做,除非您熟悉asp.net http工作流的底层修补。没有什么是可以撤销的,但是如果您从未听说过HttpHandler,那么将会有一个学习曲线

如果您想完全跳过WebForms引擎,可以创建一个自动解析HTML文件的
IHttpHandler
。这肯定会比在ASPX引擎上进行叠加要好——谁知道呢,甚至可能比使用web控件进行类似数量的服务器端处理还要快。然后,您可以为特定的扩展(如
htm
html

另一种自动拦截的方法是路由。您可以毫不费力地在webforms应用程序中使用MVC路由库,然后您可以创建与您想要的任何模式匹配的路由(同样,可能是
*.html
),并将处理传递给自定义
IHttpHandler
或类。在本例中,您正在做所有事情:您将需要查看路径,从文件系统加载文件,使用CsQuery解析它,并流式处理响应

当然,使用这两种机制,您都需要一种方法来告诉您的项目每个页面要运行哪些代码。也就是说,仅仅因为您创建了一个漂亮的HTML解析器,那么如何告诉它为该页面运行正确的“代码隐藏”

MVC只需定位一个名为“PageNameController.cs”的控制器并调用一个与参数名匹配的方法即可实现这一点。你可以做任何你想做的事;e、 g.您可以添加一个元素:

<script type="controller" src="MyPageController"></script>


您的泛型处理程序代码可以查找这样的元素,然后使用反射来定位要调用的正确命名类和方法。这相当复杂,超出了这个答案的范围;但是,如果你想构建一个全新的框架或其他东西,你就应该这样做。

在发送页面之前拦截页面内容相当简单。不久前,我在一个动态压缩内容的项目中这样做了:(这很难看,但它完成了它的工作,您可能能够修复一些代码)。无论如何,您要做的是:

1) 创建一个流对象,在调用Flush之前保存页面内容。例如,我在我的压缩项目中使用了这个:就像我之前说过的,它并不漂亮。但我的观点是,您需要创建自己的流类来完成您想要的任务(在本例中,为您提供页面的字符串输出,解析/修改字符串,然后将其输出给用户)

2) 将页面的筛选器对象分配给它。(Page.Response.Filter)请注意,您需要尽早完成此操作,以便捕获所有内容。我使用一个在PreRequestHandlerExecute事件上运行的HTTP模块实现了这一点。但是如果你做了这样的事情:

    protected override void OnPreInit(EventArgs e)
    {
        this.Response.Filter = new MyStream();
        base.OnPreInit(e);
    }
这也很可能奏效

3) 您应该能够使用类似的方法来解析HTML并从中修改它


在我看来,这似乎是最简单的方法。

在发送页面之前拦截页面内容相当简单。不久前,我在一个动态压缩内容的项目中这样做了:(这很难看,但它完成了它的工作,您可能能够修复一些代码)。无论如何,您要做的是:

1) 创建一个流对象,在调用Flush之前保存页面内容。例如,我在我的压缩项目中使用了这个:就像我之前说过的,它并不漂亮。但我的观点是,您需要创建自己的流类来完成您想要的任务(在本例中,为您提供页面的字符串输出,解析/修改字符串,然后将其输出给用户)

2) 将页面的筛选器对象分配给它。(Page.Response.Filter)请注意,您需要尽早完成此操作,以便捕获所有内容。我使用一个在PreRequestHandlerExecute事件上运行的HTTP模块实现了这一点。但是如果你做了这样的事情:

    protected override void OnPreInit(EventArgs e)
    {
        this.Response.Filter = new MyStream();
        base.OnPreInit(e);
    }
这也很可能奏效

3) 您应该能够使用类似的方法来解析HTML并从中修改它


对我来说,这似乎是最简单的方法。

我对这种方法没有答案,但如果你想编写可重用的CSS,我建议你学习一种CSS生成语言,比如or。嗯,这种方法可能会导致严重的性能问题(实现最终的H