【问题标题】:Simulate the page lifecycle to grab the html from the UI layer模拟页面生命周期从 UI 层抓取 html
【发布时间】:2010-12-16 10:46:34
【问题描述】:

我正在使用一个相当大的 .net Web 应用程序。

用户希望能够将报告导出为 PDF。由于报告基于多层数据的聚合,因此获得准确快照的最佳方法是实际拍摄 UI 快照。我可以获取 UI 的 html 并将其解析为 PDF 文件。

由于 UI 可能需要长达 30 秒的时间来加载,但结果永远不会改变,所以我想在项目保存到后台线程后立即缓存一个 pdf。

我对这种方法的主要担心是,如果我通过 UI,我必须担心超时。虽然后台线程等可以持续多久,但 aspx 页面只能持续很长时间,直到它们被终止。

我有两个想法来解决这个问题。第一个想法是创建一个加载 UI、覆盖渲染并将渲染数据存储到数据库的 aspx 页面。后台线程会在内部向该页面发出 WebRequest,然后从数据库中获取结果。这显然必须考虑安全性,并且如果 UI 生成时间过长,还需要担心超时。

另一个想法是创建一个页面对象并在代码中手动填充它,手动调用相关方法,然后从中获取数据。该方法的问题,除了不知道怎么做之外,我担心我可能会忘记调用一个方法,或者某些东西可能无法正常工作,因为它实际上并没有与真正的会话或网络服务器相关联。

在后台线程中模拟页面 UI 的最佳方式是什么?

【问题讨论】:

  • @RickNZ:由于需要付出的努力,它不在我的列表顶部,但是如果您能想出一种方法来解决 webrequest 会导致的超时问题和创建页面的周期问题在后台线程中会导致,我全神贯注。

标签: c# .net multithreading asp.net


【解决方案1】:

我知道 3 种可能的解决方案:

IHttpHandler

This question 有完整的答案。一般的问题是您通过实现自己的可读流和自定义IHttpHandler 来捕获Response.Filter 输出。

这不允许您远程捕获页面的输出,但是它只允许您捕获将预先发送到客户端的 HTML,并且必须调用该页面。因此,如果您使用单独的页面生成 PDF,则必须调用该页面。

网络客户端

我可以看到使用 ASP.NET 执行此操作的唯一替代方法是使用阻塞 WebClient 来请求生成 HTML 的页面。获取该输出,然后将其转换为 PDF。在你做这一切之前,你显然可以检查你的缓存,看看它是否已经在里面了。

WebClient client = new WebClient();
string result = client.DownloadString("http://localhost/yoursite");

WatiN(或其他浏览器自动化包)

另一个可能的解决方案是WatiN,它为您提供了很大的灵活性来捕获浏览器的 HTML。这样做的挫折是它需要与桌面交互。这是他们的例子:

using (IE ie = new IE("http://www.google.com"))
{
    ie.TextField(Find.ByName("q")).TypeText("WatiN");
    ie.Button(Find.ByName("btnG")).Click();

    Assert.IsTrue(ie.ContainsText("WatiN"));
}

【讨论】:

  • 谢谢。 Webrequest 是我最初使用的解决方案。它在本地盒子上完美运行。我对这些方法的担忧是超时——如果服务器被无理地敲打并且本地调用的 aspx 超时,则可能存在问题。显然我可以使用某种计时器来重试,但如果用户现在需要它,那不是一个选项。
【解决方案2】:

如果“获得准确快照的最佳方法是实际拍摄 UI 快照”是真的,那么您需要重构您的代码。

构建一个数据提供程序,为 UI 和 PDF 生成器提供聚合数据。分层你的系统。

然后,在构建 PDF 时,您只需调用一个位置,无需处理棘手的 UI 拦截/多线程问题。

【讨论】:

  • +1,虽然目前它可能不是一个可行的解决方案,但至少可以朝着这个方向努力。
  • 我们第一次进行了这个迭代。它变成了维护的噩梦。最终,有人会在 UI 中创建特殊的逻辑,甚至像“如果项目来自法国以不同的方式显示表格,现在将此单元格涂成绿色,在此处更改拼写”这样简单的操作,它不会反映在导出中因为 ascx 和 pdf 输出都需要匹配,最终事情会不同步。这尤其适用于只想编辑 ascx 页面并且甚至不考虑导出的人,因为这不是他们的工作。
  • 由于您的开发人员缺乏必要的纪律,您将通过截屏 PDF 来完成艰巨的工作?我为你感到;这不是一个理想的情况。
  • 嗯...也许您应该考虑调整模型-视图-视图模型模式。基本上为您的“自定义 UI 逻辑”添加另一层(ViewModel)并将这些决定放在那里。然后让您的 ASPX 和 PDF 渲染器都绑定到该模型和逻辑。
  • 我仍然不明白如何创建一个视图模型来替代 ascx 页面中对自定义代码的需求——我的意思是,假设我更改了样式表?我怎样才能让每个 PDF 都级联? ascx中继器之类的呢?操作 DOM 的 javascript 怎么样?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多