代码之家  ›  专栏  ›  技术社区  ›  Jamie Treworgy

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

  •  1
  • Jamie Treworgy  · 技术社区  · 15 年前

    This question

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

        default.aspx:
       <a id="link1" href="#">Click Here</a>
       <div id="container">
       <asp:PlaceHolder id="MyPlaceholder" runat="server" />
       </div>
        <script type="text/javascript">
            $(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();
            }
        }
    

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

    基本上,如果在没有“ajax”查询字符串的情况下调用页面,那么它的行为就像它自己一样。但是当使用这个querystring时,它会截取我所关心的内容(一个名为TestUserControl.ascx的用户控件)的输出流并呈现 . 这将返回给客户端,客户端将更新HTML。所有的id都将像以前一样被重新创建,因为我并不是试图孤立地呈现那个控件,而是在它自己的页面上下文中。理论上,ASP.NET创造的每一点魔力都应该通过ajax查询进行复制、检索和更新。

    除了明显缺乏效率外,在这个小小的测试中,它似乎运行得很顺利。我可以使用服务器生成的HTML完全重新提交控件,而无需回发,而且我已经编写了零个javascript。这个例子实际上没有改变任何东西,但是传递更多的参数来改变输出是很简单的。

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

    如果服务器性能不是一个问题,那么使用ASP.NET服务器控件的所有优点获得大量功能似乎是一种非常简单的方法。但我似乎找不到任何关于在实践中使用这种技术的讨论,所以我想知道我可能遗漏了什么。

    3 回复  |  直到 9 年前
        1
  •  2
  •   Frédéric Hamidi    15 年前

    好吧,首先,你要发送一个 GET 请求您的页,这样您要更新的控件将不会收到最新的表单数据。更重要的是, ViewState

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

    幸运的是, others 已经解决了那些问题。我建议你把你的用户控件放在 UpdatePanel force a refresh 从客户端:

    __doPostBack("yourUpdatePanelClientID", "");
    
        2
  •  0
  •   Dave Ward    15 年前

    如果替代方法是使用UpdatePanel,那么肯定值得考虑部分呈现。即使使用UpdatePanel只更新页面的一小部分,这些更新也必须将整个ViewState发送回服务器,服务器必须 run the entire page through its life cycle ,渲染它,然后提取部分区域。你拿 a significant performance hit

    在您的例子中,由于您在ASPX pae中呈现该部分内容,因此仍然会导致页面生命周期命中。它没有UpdatePanel那么糟糕,但是没有必要。

    我发现了 splitting the partial rendering out to a web service or HttpHandler handler 效果很好。它是 许多的

    缺点是用户控件内的控件无法处理回发。您当然可以重新呈现它和/或传入参数来控制它的呈现,但是您不能使用它来呈现GridView并期望它的分页链接起作用,例如。

        3
  •  0
  •   Mike    14 年前

    我希望有更多关于将ASP.NET web表单移到现代的讨论。我得自己解决大部分问题。我个人致力于寻找最简单的解决方案,并避免所有需要在更多的Microsoft上分层的解决方案。没有什么反对微软的,我只是想保持它的简单和使用普通的网络标准。

    到目前为止,我已经能够使用jQuery load来AJAX关闭我尝试过的所有东西。没有简单的答案,但是如果你坚持不懈,你可能可以解决任何由旧式ASP.NET实践引起的客户端问题。

    我认为最重要的是停止使用ViewState。完全正确。这会迫使你放弃许多会给你的客户带来麻烦的糟糕做法。这其实比你想象的要容易。在那一点上,把东西放下来通常是可行的。甚至是数据网格。做你自己的分页,不管是客户端还是服务器端,都没那么难,然后你可以在任何地方重用你的解决方案。

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