查看我的 CsQuery 项目:https://github.com/jamietre/csquery 或在 nuget 上作为“CsQuery”。
这是 jQuery 的 C# (.NET 4) 端口。在基本性能测试(包含在项目测试套件中)中,选择器比 HTML Agility Pack + Fizzler(HAP 的 css 选择器插件)快大约 100 倍;在典型的网站上实时操作输出流非常快。如果你是 amazon.com 什么的,当然是 YMMV。
我开发它的最初目的是从内容管理系统中操作 HTML。启动并运行它后,我发现使用 CSS 选择器和 jQuery API 比使用 Web 控件有趣得多,并开始将其用作服务器渲染页面的主要 HTML 操作工具,并将其构建为涵盖几乎所有的 CSS、jQuery 和浏览器 DOM。从那以后我再也没碰过网络控件。
要使用 CsQuery 拦截 Web 表单中的 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 中做同样的事情,请参阅 this blog post 描述。
GitHub 上有 CsQuery 的基本文档。除了输入和输出 HTML 之外,它的工作方式与 jQuery 非常相似。上面的WebForms 对象只是为了帮助您处理与HtmlTextWriter 对象和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>");
此外,几乎整个浏览器 DOM 都可以使用您使用的相同方法获得
在浏览器中。索引器 [0] 返回选择集中的第一个元素,如 jquery;如果你习惯写 javascript 来操作 HTML 应该很熟悉。
// "Select" method is the same as the property indexer [] we used above.
// I go back and forth between them to emphasise their interchangeability.
var element = dom.Select("div > input[type=checkbox]:first-child")[0];
a.Checked=true;
当然,在 C# 中,您可以使用大量其他通用工具,例如 LINQ。或者:
var element = dom["div > input[type=checkbox]:first-child"].Single();
a.Checked=true;
当您完成对文档的操作后,您可能想要获取 HTML:
string html = doc.Render();
仅此而已。 CQ 对象上有大量的方法,涵盖了所有 jQuery DOM 操作技术。还有一些处理 JSON 的实用方法,它广泛支持动态和匿名类型,以使传递数据结构(例如一组 CSS 类)尽可能简单——就像 jQuery。
一些更高级的东西
除非您熟悉 asp.net 的 http 工作流程的低级修补,否则我不建议您这样做。没有什么是可以撤消的,但如果您从未听说过 HttpHandler,就会有一个学习曲线。
如果您想完全跳过 WebForms 引擎,您可以创建一个自动解析 HTML 文件的IHttpHandler。这肯定会比覆盖在 ASPX 引擎上执行得更好——谁知道呢,甚至可能比使用 Web 控件进行类似数量的服务器端处理还要快。然后您可以register your handler using web.config 获取特定的扩展名(例如htm 和html)。
另一种自动拦截的方法是使用路由。您可以在 webforms 应用程序中毫无问题地使用 MVC 路由库,here's one description of how to do this. 然后您可以创建一个匹配您想要的任何模式的路由(同样,也许是 *.html)并将处理传递给自定义 IHttpHandler 或类.在这种情况下,您正在做所有事情:您需要查看路径,从文件系统加载文件,使用 CsQuery 解析它,然后流式传输响应。
当然,使用任何一种机制,您都需要一种方法来告诉您的项目要为每个页面运行什么代码。也就是说,仅仅因为您已经创建了一个漂亮的 HTML 解析器,那么您如何告诉它为该页面运行正确的“隐藏代码”?
MVC 只需找到一个名为“PageNameController.cs”的控制器并调用与参数名称匹配的方法即可。你可以为所欲为;例如你可以添加一个元素:
<script type="controller" src="MyPageController"></script>
您的通用处理程序代码可以查找这样的元素,然后使用反射来定位要调用的正确命名类和方法。这非常复杂,超出了这个答案的范围;但是,如果您正在寻找构建一个全新的框架或其他东西,这就是您要做的事情。