使用ajax更新ASP.NET服务器呈现的控件

这个问题让我思考如何做一个相对可撤销的事情:从ASP.NET无缝集成服务器生成的HTML和通过javascript进行客户端控制。 当然,您始终可以使用javascript / jquery / libraries来创建相同的显示客户端。 但在大多数情况下,更容易在服务器上进行所有渲染,而不是仅仅将数据传递给必须处理用户界面和渲染的客户端控件。 或者你可能已经有很多交互性较低的服务器代码,你真的不想完全重新使用javascript库来添加一些更好的交互性。

我有一个似乎在基本的概念certificate中起作用的理论。 假设您希望基于客户端事件完全重新呈现服务器生成的控件的HTML,而不进行回发。 所以使用jquery,我有一个页面:

default.aspx: Click Here 
$(document).ready(function() { $('#link1').click(function() { $.ajax({ url: "default.aspx", type: "GET", dataType: "html", async: true, data: { "ajax": "1" }, success: function(obj) { // replace the HTML $('#container').html(obj); } }); }); });

该事件使其使用ajax查询自身。 做诡计的代码隐藏是这样的:

  TestUserControl ctl; string ajax; protected void Page_Load(object sender, EventArgs e) { ctl = (TestUserControl)Page.LoadControl("TestUserControl.ascx"); Myplaceholder.Controls.Add(ctl); ctl.OnRender += new TestuserControl.RenderHandler(ctl_Render); } protected void Page_PreRender() { ajax = Request.QueryString["ajax"] == null ? "" : Request.QueryString["ajax"]; } void ctl_Render() { if (ajax == "1") { StringBuilder sb = new StringBuilder(); StringWriter sw = new StringWriter(sb); using (HtmlTextWriter writer = new HtmlTextWriter(sw)) { ctl.DoRender(writer); } Response.Write(sb.ToString()); Response.End(); } } 

在TestUserControl中,我公开base.render以获取输出:

  public void DoRender(HtmlTextWriter writer) { base.Render(writer); } 

基本上,如果在没有“ajax”查询字符串的情况下调用页面,它就像它自己一样。 但是当使用该查询字符串时,它会拦截我所关注的内容(一个名为TestUserControl.ascx的用户控件)的输出流并呈现 。 这将返回给客户端,客户端会更新HTML。 所有的ID都将像以前一样完全重新创建,因为我不是试图单独渲染该控件,而是在其自己的页面的上下文中。 从理论上讲,ASP.NET创建的每一个魔法都应该通过ajax查询进行复制,检索和更新。

除了明显缺乏效率之外,它似乎在这个小小的测试中游泳。 我可以使用服务器生成的HTML完全重新呈现控件而无需回发,并且我写了零javascript。 此示例实际上并未更改任何内容,但传递更多参数以更改输出会很简单。

我想知道是否有人在实践中尝试过这样的事情? 我可能没有想到哪些潜在的问题?

如果服务器性能不是问题,那么看起来很容易通过ASP.NET服务器控件的所有好处获得大量function。 但我似乎无法找到任何关于在实践中使用这种技术的讨论,所以我想知道我可能会缺少什么。

好吧,对于初学者,您正在向您的页面发送GET请求,因此您要更新的控件将不会收到最新的表单数据。 更重要的是,除非您的用户控件非常简单,否则ViewState将丢失,您可能不希望这样。

您可以通过使用POST请求来解决此问题,但是还有其他潜在的问题,例如,您是否可以保证嵌入在用户控件中的客户端脚本可以再次运行,或者在所有浏览器上一致地更新它时不会运行?

幸运的是, 其他人已经解决了这些问题。 我建议您将用户控件放在UpdatePanel中并强制从客户端刷新 :

 __doPostBack("yourUpdatePanelClientID", ""); 

如果替代方案是使用UpdatePanel,那么考虑部分渲染绝对值得。 即使您只使用UpdatePanel更新页面的一小部分,这些更新也必须将整个ViewState发送回服务器,服务器必须在整个生命周期内运行整个页面 ,渲染它,然后提取部分区域。 为方便起见,您的性能受到重创 。

在您的情况下,由于您在ASPX pae中呈现部分内容,因此您仍然会遇到页面生命周期。 它没有UpdatePanel那么糟糕,但不必要。

我发现将部分渲染拆分为Web服务或HttpHandler处理程序效果很好。 它比在WebForms中渲染部分的大多数其他方法快得多,但仍然允许使用用户控件进行模板的灵活性。

缺点是用户控件内的控件无法处理PostBack。 你绝对可以重新渲染它和/或传递参数来控制它的渲染,但是你不能使用它来渲染GridView并期望它的分页链接工作。

我希望有更多关于将ASP.NET Web表单移动到现代时代的讨论。 我必须自己弄清楚大部分事情。 我个人努力寻求最简单的解决方案,并避免所有需要在更多Microsoft上进行分层的解决方案。 没有什么可以对抗MS,我只想保持简单并使用普通的Web标准。

到目前为止,我已经能够使用jQuery加载AJAX了解我尝试过的所有内容。 没有轻拍,简单的答案,但如果你坚持不懈,你可以解决因旧学校ASP.NET实践导致的任何客户端问题。

我认为最重要的事情是停止使用ViewState。 完全。 这将迫使您摆脱许多可能导致您在客户端出现问题的可怕做法。 这实际上比您想象的更容易。 在这一点上,AJAXing的东西通常会起作用。 甚至DataGrids。 做自己的分页,无论是客户端还是服务器端,都不是那么难,然后你可以在任何地方重用你的解决方案。

问题将来自您无法控制的第三方内容。 在这些情况下,您可以使用IE开发人员工具(F12)来查看ASP.NET最初发送的内容。 最糟糕的情况是,你必须自己编写一些JavaScript并运行它。 在实践中,我很少做任何可怕的事情。 我想如果你使用了很多重量级控制器,这将是不切实际的,但在这种情况下你已经买了这个农场。