查看我的 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 中做同样的事情,请参阅描述该内容的博客文章。
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 引擎,您可以创建一个IHttpHandler
自动解析 HTML 文件的引擎。这肯定会比覆盖在 ASPX 引擎上执行得更好——谁知道呢,甚至可能比使用 Web 控件进行类似数量的服务器端处理还要快。然后,您可以使用 web.config为特定扩展名(如htm
和html
)注册您的处理程序。
另一种自动拦截的方法是使用路由。您可以在 webforms 应用程序中毫无问题地使用 MVC 路由库,这里有一个关于如何做到这一点的描述。然后,您可以创建一个匹配您想要的任何模式的路由(同样,也许*.html
)并将处理传递给自定义IHttpHandler
或类。在这种情况下,您正在做所有事情:您需要查看路径,从文件系统加载文件,使用 CsQuery 解析它,然后流式传输响应。
当然,使用任何一种机制,您都需要一种方法来告诉您的项目为每个页面运行什么代码。也就是说,仅仅因为您已经创建了一个漂亮的 HTML 解析器,那么您如何告诉它为该页面运行正确的“隐藏代码”?
MVC 通过定位一个名称为“PageNameController.cs”的控制器并调用与参数名称匹配的方法来做到这一点。你可以为所欲为;例如,您可以添加一个元素:
<script type="controller" src="MyPageController"></script>
您的通用处理程序代码可以查找这样的元素,然后使用反射来定位要调用的正确命名类和方法。这非常复杂,超出了这个答案的范围;但是,如果您正在寻找构建一个全新的框架或其他东西,这就是您将如何去做的事情。