在MasterPage中使用LinkButton触发UpdateProgress中的问题
这个问题在满足下面几个条件时产生:
1. 使用了MasterPage。
2. 使用LinkButton来触发UpdateProgress。
3. 通过JS的prm.add_initializeRequest(或者PageLoad)来得到触发对象的ID
4. 项目中加入了 AjaxControlToolkit.dll 的引用。(只需要加入引用就会发生错误,哪怕页面上没有使用AjaxControlToolkit的控件)
当满足这4个条件是,JS会出现错误。
源码如下:
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server"> <asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server"></asp:ScriptManagerProxy> <asp:LinkButton ID="LinkButton1" runat="server" onclick="LinkButton1_Click">Go Go Go</asp:LinkButton> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:GridView ID="FarGridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="role_id" AllowPaging="True" PageSize="3" AllowSorting="True"> <Columns> <asp:BoundField DataField="role_id" HeaderText="role_id" InsertVisible="False" ReadOnly="True" SortExpression="role_id" /> <asp:BoundField DataField="role_name" HeaderText="role_name" SortExpression="role_name" /> <asp:BoundField DataField="role_permission" HeaderText="role_permission" SortExpression="role_permission" /> <asp:CheckBoxField DataField="role_delete" HeaderText="role_delete" SortExpression="role_delete" /> <asp:CheckBoxField DataField="role_default" HeaderText="role_default" SortExpression="role_default" /> </Columns> </asp:GridView> </ContentTemplate> <Triggers><asp:AsyncPostBackTrigger ControlID="LinkButton1" EventName="Click" /></Triggers> </asp:UpdatePanel> <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" DisplayAfter="10"> <ProgressTemplate><strong>please Wait...</strong></ProgressTemplate> </asp:UpdateProgress> <script type="text/javascript"> //<![CDATA[ var prm = Sys.WebForms.PageRequestManager.getInstance(); prm.add_initializeRequest(InitializeRequest); prm.add_endRequest(EndRequest); var postBackElement; function InitializeRequest(sender, args) { if (prm.get_isInAsyncPostBack()) args.set_cancel(true); postBackElement = args.get_postBackElement(); if (postBackElement.id == 'ContentPlaceHolder1_LinkButton1') { $get('ContentPlaceHolder1_UpdateProgress1').style.display = 'block'; } } function EndRequest(sender, args) { if (postBackElement.id == 'ContentPlaceHolder1_LinkButton1') { $get('ContentPlaceHolder1_UpdateProgress1').style.display = 'none'; } } //]]> </script> </asp:Content>
这时,当你点击"Go GO GO"这个LinkButton的时候,不会产生回发,会出现一个JS的错误:
postBackElement = args.get_postBackElement(); // 这条语句错误
postBackElement 是undefined 的错误。
一个很奇怪的问题,当我不使用MasterPage,或者使用Button代替LinkButton,或者不显示UpdateProgress,或者不引用AjaxControlToolkit.dll的时候,一点问题都没有。
解决办法:
问题出在LinkButton的ClientIDMode上,默认的ClientIDMode是Inherit,这个会导致错误,只有手动将ClientIDMode设为AutoID,才能正常运行。
当ClientIDMode为Inherit时,LInkButton的ClientID是:ContentPlaceHolder1_LinkButton1,
当ClientIDMode为AutoID时,LInkButton的ClientID是 ctl00_ContentPlaceHolder1_LinkButton1,正是由于产生的ClientID不同,导致了上面的错误。
通过查看JS源码,可以知道Ajax初始化的时候,产生的ID是对应AutoID的。
<script type="text/javascript">
//<![CDATA[
Sys.WebForms.PageRequestManager._initialize('ctl00$ContentPlaceHolder_main$ScriptManager1', 'farform', ['tctl00$ContentPlaceHolder_main$up_main','ContentPlaceHolder_main_up_main'], ['ctl00$ContentPlaceHolder_main$uc_search','ContentPlaceHolder_main_uc_search_btn_search','ctl00$ContentPlaceHolder_main$btn_del',''], [], 0, 'ctl00');
//]]>
</script>