选择文件后ASP.NET用户控件脚本触发上传按钮后台代码不执行问题
问题分析与解决方案
嘿,我帮你排查了下这个问题,核心有两个关键点导致脚本触发上传时后台代码不执行:
1. 客户端脚本的语法错误
你看你的confirm_user函数里,setoverride被定义在了return false;之后,还嵌套在confirm_user内部!这就导致这个函数根本无法被外部调用,后台通过ScriptManager.RegisterStartupScript注册的setoverride脚本执行时会报错,override变量永远是初始值-1,脚本逻辑完全没按预期走。
修复脚本结构
把setoverride移到confirm_user外面,确保它能被正常访问:
//hold Check state var override = -1; // 把这个函数移到confirm_user外面! function setoverride(ov) { override = ov; alertify.alert('Info','Test: '+ ov); } //Script is working, except Click() function confirm_user() { if (override == 1) { if (confirm('Overrride?')) { document.getElementById('<%=btn_upload_nocheck.ClientID%>').click(); return true; } else return false; } else if (override == 0) { document.getElementById('<%=btn_upload_nocheck.ClientID%>').click(); return true; } return false; }
2. UpdatePanel的异步回发不支持文件上传
UpdatePanel的异步回发(AJAX)是不支持携带文件数据的,当你通过脚本触发btn_upload_nocheck的点击时,默认会走UpdatePanel的异步回发逻辑,导致文件数据无法被后台接收,看起来就像后台代码没触发。而直接点击按钮时,浏览器会发起全页回发,所以能正常上传。
强制上传按钮触发全页回发
在你的UpdatePanel里添加PostBackTrigger,指定btn_upload_nocheck触发全页回发:
<asp:UpdatePanel runat="server" ID="up_message"> <ContentTemplate> <!-- 原有DropDownList和Label内容 --> </ContentTemplate> <!-- 添加这个触发器 --> <Triggers> <asp:PostBackTrigger ControlID="btn_upload_nocheck" /> </Triggers> </asp:UpdatePanel>
3. 优化后台的提示消息方法
你原来的ShowMessage直接用Response.Write输出脚本,这在UpdatePanel的异步回发中会破坏页面结构,改用ScriptManager.RegisterStartupScript来注册提示脚本更安全:
private void ShowMessage(string msg) { // 转义单引号避免脚本语法错误 string escapedMsg = msg.Replace("'", "\\'"); ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "uploadMsg", $"alert('{escapedMsg}');", true); }
完整修复后的关键代码片段
ASCX部分
<%@ Control Language="C#" AutoEventWireup="True" Inherits="Test_Web.UploadProgress" Codebehind="UploadProgress.ascx.cs"%> <link rel="stylesheet" href="css/alertify.css" /> <link rel="stylesheet" href="css/themes/default.css" /> <script src="alertify.js"></script> <script type='text/javascript'> //hold Check state var override = -1; function setoverride(ov) { override = ov; alertify.alert('Info','Test: '+ ov); } function confirm_user() { if (override == 1) { if (confirm('Overrride?')) { document.getElementById('<%=btn_upload_nocheck.ClientID%>').click(); return true; } else return false; } else if (override == 0) { document.getElementById('<%=btn_upload_nocheck.ClientID%>').click(); return true; } return false; } </script> <asp:ScriptManager runat="server"></asp:ScriptManager> <asp:UpdatePanel runat="server" ID="up_message"> <ContentTemplate> <asp:DropDownList runat="server" ID="dd_sendungstitle" OnSelectedIndexChanged="dd_sendungstitle_SelectedIndexChanged" AutoPostBack="True"> <asp:ListItem>t1</asp:ListItem> <asp:ListItem>t2</asp:ListItem> <asp:ListItem>t3</asp:ListItem> <asp:ListItem>t4</asp:ListItem> </asp:DropDownList> <asp:Label runat="server" ID="lbl_progress"></asp:Label> </ContentTemplate> <Triggers> <asp:PostBackTrigger ControlID="btn_upload_nocheck" /> </Triggers> </asp:UpdatePanel> <br/> <input type="file" id="upUserCtrl" runat="server"/> <br/> <asp:Button ID="btn_upload_nocheck" runat="server" Text="Upload" Width="101px" align="center" OnClick="btn_upload_nocheck_Click"/> <asp:Button runat="server" ID="btnTest" OnClientClick="return confirm_user();" Text="Upload Script"/>
后台关键代码
private void ShowMessage(string msg) { string escapedMsg = msg.Replace("'", "\\'"); ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "uploadNotification", $"alert('{escapedMsg}');", true); } protected void dd_sendungstitle_SelectedIndexChanged(object sender, EventArgs e) { // Do Checking STuff if (dd_sendungstitle.SelectedIndex == 0 || dd_sendungstitle.SelectedIndex == 3) { _override = 0; } else { _override = 1; } //Set Client Script ScriptManager.RegisterStartupScript(Page,typeof(string), "setOverrideScript", $"setoverride({_override});", true); }
按照这些步骤修复后,脚本触发的上传应该就能正常调用后台代码了,而且文件也能正确上传。
内容的提问来源于stack exchange,提问作者DarkRider
相关产品推荐
相关产品推荐

