【问题标题】:AutoPostBack: true vs falseAutoPostBack:真与假
【发布时间】:2013-07-31 19:06:38
【问题描述】:

在我开始之前,我已经看到了this question about a very similar topic(以及this onethis one),它们都没有完全回答我的问题。我已经了解这些问题/答案中提出的概念,但我还有更多问题。

A) 如果您有多个带有AutoPostBack="false" 的控件并且您在回发之前更改了其中的多个控件,会发生什么情况?以下面的简短示例为例(假设页面所需的所有其他内容都正确且简单地编写;例如,Page_Load):

默认.aspx:

<asp:DropDownList ID="ddlFoo" runat="server" 
    OnSelectedIndexChanged="ddlFoo_Changed" AutoPostBack="false" >
    <asp:ListItem Text="a" />
    <asp:ListItem Text="b" />
    <asp:ListItem Text="c" />
</asp:DropDownList>
<asp:DropDownList ID="ddlBar" runat="server" 
    OnSelectedIndexChanged="ddlBar_Changed" AutoPostBack="false" >
    <asp:ListItem Text="1" />
    <asp:ListItem Text="2" />
    <asp:ListItem Text="3" />
</asp:DropDownList>
<asp:Button ID="btnQux" runat="sever" Text="Click for PostBack" OnClick="btnQux_Click"

默认.aspx.cs:

protected void ddlFoo_Changed(object sender, EventArgs e)
{
    Response.Write("ddlFoo changed to " + ddlFoo.Text + ". ");
}
protected void ddlBar_Changed(object sender, EventArgs e)
{
    Response.Write("ddlBar changed to " + ddlBar.Text + ". ");
}
protected void btnQux_Changed(object sender, EventArgs e) { }

现在,假设您将ddlFoo 更改为3,然后将ddlBar 更改为b。然后,单击btnQux。点击后您会从Response.Write 获得以下输出:

ddlBar changed to b. ddlFoo changed to 3. 

为什么会这样? OnSelectedIndexChanged 方法是否会被放入堆栈中以便在回发发生时调用?

B) 为什么当我使用这种方法并为我的大多数控件设置AutoPostBack="false" 时,我的网页加载得更快?具体而言,我对 CheckBoxDropDownListGridView 中的TextBox 执行了此操作,它们检索了约1200 行和27 列数据,并且在VS2008 调试模式下花费了10 秒,而之前是310 秒。为什么加载/刷新时间会这么快?

编辑:我今天下午早些时候发布了代码,旧 (AutoPostBack="true") 和新 (AutoPostBack="false") 版本的加载时间没有显着差异。我认为也许调试器正在做一些额外的事情,这导致加载时间大幅增加。改写问题 B) 的更好方法可能是这样:调试器一直在做什么来导致加载时间如此大的跳跃?

【问题讨论】:

    标签: c# asp.net autopostback


    【解决方案1】:

    警告:我不是 ASP.NET 专家...如果这被证明是垃圾,我会删除它:)

    A) 我相信您将看到所有控件的新值,无论何时回发最终发生,包括所有更改事件,正如您所描述的那样。毕竟值已经改变了——AutoPostBack 只会影响时间(当然还有回发是否发生)。

    B) 在所有控件上使用AutoPostBack = True 提供的 HTML 中有更多的 Javascript,但不足以产生巨大的差异。正如您在编辑中指出的那样,无论如何,这似乎是一个暂时性问题 - 如果没有更多诊断,我们无法真正解释暂时性问题。

    【讨论】:

    • 实际上,这非常精确。 AutoPostBack 只会强制页面发布到服务器。如果有绑定到控件的事件处理程序,则尽管有AutoPostBack="false",但该事件将被堆叠。 msdn.microsoft.com/en-us/library/8cb3cz8e(v=vs.100).aspx
    • 我按照您的建议查看了源代码。在我的控件上使用AutoPostBack="true",代码为4.98 MB;设置为 false,它是 4.57 MB。它们的大小肯定存在差异,我确实注意到真实版本中有相当多的 JavaScript。感谢您的洞察力
    • @wlyles:虽然大小上的差异并不能真正解释那么多的时间差异。我认为您应该进一步了解时间的去向。你是怎么测量的?是响应提供之前的时间,还是在浏览器上完成呈现之前的时间? (在这种情况下,可能会花费时间在浏览器上执行 Javascript,但那是很多时间......)
    • @JonSkeet 是的,我也是这么想的。它不应该有这样的不同。我只是从按下 F5(开始调试)开始计时,直到页面允许我单击控件来更改它们的值。似乎大部分时间都用于渲染,因为页面顶部的&lt;div&gt; 元素和GridView 的前几行在几秒钟内可见,但GridView 的其余部分需要一段时间
    • 我今天下午早些时候发布了代码,旧(AutoPostBack="true")和新(AutoPostBack="false")版本的加载时间没有显着差异。我认为也许调试器正在做一些额外的事情,这导致加载时间大幅增加。
    【解决方案2】:

    您可以使用Fiddler 查看客户端和服务器之间正在移动的数据。

    答。使用 fiddler,您可以轻松查看发送到服务器的数据。

    例如:

    如果你有 DropDownList ddlFoo,当你点击按钮时,你实际上发布了这个信息:

    POST http:// [server]:[port]/[resource.aspx] HTTP/1.1 Host: [server]:[port] [标题...]

    _VIEWSTATE[作为隐藏字段值存储在 html 中的视图状态数据]&_EVENTVALIDATION=[事件验证 数据]&ddlFoo=selecteItem&button1=ButtonText

    当 ASP.NET 收到请求时,它会比较 ddlFoo 的值并调用它的事件。

    B. 当你将 AutoPostBack 设置为 true 时,就会生成这个 javascript 函数:

    function __doPostBack(eventTarget, eventArgument) {
        if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
            theForm.__EVENTTARGET.value = eventTarget;
            theForm.__EVENTARGUMENT.value = eventArgument;
            theForm.submit();
        }
    }
    

    并且onchange属性会被添加到ddlFoo中。因此,每当您更改 DropdownList 项时,都会触发 onchange 事件并调用 __doPostBack 函数,该函数将自动回发到服务器。

    【讨论】:

      【解决方案3】:

      到目前为止,您得到的两个答案都是正确的。它的简化版是这样的:

      A) 当表单最终被 POST 到服务器时,服务器会将表单的当前状态与 ViewState 进行比较并做出相应的响应。

      B) 启用 AutoPostBack 会导致生成 javascript,并且此 javascript 提交表单(然后触发回发)。

      【讨论】:

        【解决方案4】:

        为什么会这样?是否放置 OnSelectedIndexChanged 方法 进入一个回发后调用的堆栈?

        不会立即回发的事件(在您的情况下为 ddlFoo_Changed 和 ddlBar_Changed)被缓存

        然后,当页面被回发(通过 btnQux 的点击事件)时,这些缓存/待处理事件与 btnQux 的点击事件一起引发。

        您可以在此处阅读更多信息 - ASP.NET Server Control Event Model

        【讨论】:

        • 感谢您的链接,这对我的第一个问题非常有用
        猜你喜欢
        • 2015-03-30
        • 1970-01-01
        • 1970-01-01
        • 2019-01-30
        • 2017-02-20
        • 1970-01-01
        • 2010-11-12
        • 2012-06-06
        相关资源
        最近更新 更多