在.NET 4.6自定义列表选择器中,如何从JS调用ASP.NET后端C#函数?
问题根源
asp:HiddenField的OnValueChanged是服务器端事件,仅在页面发生回发(PostBack)且控件值与ViewState中存储的旧值不同时才会触发。前端通过JS修改值并触发change事件只是前端行为,不会自动触发服务器回发,因此后端方法无法执行。
方案1:手动触发回发(整页/局部)
步骤1:修改前端JS逻辑
在onSelected_<%# this.ClientID %>函数末尾添加__doPostBack调用,指定回发目标为HiddenField的UniqueID(服务器端识别的唯一ID):
function onSelected_<%# this.ClientID %>(value, display) { var hidSelected = $('#<%# this.hidSelected.ClientID %>'); $(hidSelected).val(value); $('#<%# this.txtDisplay.ClientID %>').val(display); $('#modal_<%# this.ClientID %>').modal('hide'); // 触发服务器回发,告知后端HiddenField值已变更 __doPostBack('<%# this.hidSelected.UniqueID %>', ''); }
步骤2:确保服务器端事件绑定正确
保留HiddenField的事件绑定,并确保用户控件的ViewState启用(默认启用,若手动关闭需重新开启):
<asp:HiddenField OnValueChanged="onNewItemSelected" ID="hidSelected" runat="server" />
protected void onNewItemSelected(object sender, EventArgs e) { if (this.onItemChanged != null) this.onItemChanged(); }
优化:局部回发(避免整页刷新)
如果不想整页刷新,用UpdatePanel包裹用户控件的相关内容,实现局部异步回发:
<asp:UpdatePanel ID="updSelector" runat="server" UpdateMode="Conditional"> <ContentTemplate> <asp:HiddenField OnValueChanged="onNewItemSelected" ID="hidSelected" runat="server" /> <asp:TextBox ID="txtDisplay" runat="server" /> <!-- 模态框相关HTML --> </ContentTemplate> <Triggers> <!-- 指定HiddenField的ValueChanged事件为异步回发触发器 --> <asp:AsyncPostBackTrigger ControlID="hidSelected" EventName="ValueChanged" /> </Triggers> </asp:UpdatePanel>
方案2:委托传递(宿主页面触发)
若用户控件需要复用且不想依赖回发,可在用户控件中定义值变更事件,由宿主页面订阅并处理:
- 在用户控件中定义事件:
public event EventHandler ItemChanged; protected void onNewItemSelected(object sender, EventArgs e) { ItemChanged?.Invoke(this, EventArgs.Empty); }
- 宿主页面引用用户控件时订阅事件:
<uc:CustomSelector ID="Selector1" runat="server" OnItemChanged="Selector1_ItemChanged" />
protected void Selector1_ItemChanged(object sender, EventArgs e) { // 执行宿主页面的后端逻辑 }
关键注意事项
- 确保用户控件的
ViewState未被禁用,否则服务器端无法对比HiddenField的新旧值,OnValueChanged不会触发。 __doPostBack是ASP.NET内置函数,无需额外引入,但若页面未包含回发控件(如Button),需添加一个隐藏的Button控件确保页面生成该函数。
内容的提问来源于stack exchange,提问作者Axiyom
相关产品推荐
相关产品推荐

