ASP.NET GridView OnClientClick传参调用JS报服务器标记错误
问题原因
你在GridView内使用ImageButton调用JS函数display(id)时,参数id取自绑定的ObjectDataSource数据源,初始写法因为服务器控件属性的双引号嵌套问题触发解析错误,原错误代码如下:
<asp:ImageButton ID="imgbut" runat="server" src="/images/gimage.jpg" OnClientClick="display('<%# Eval("id") %>')" />
运行后抛出错误:
服务器标记不正确
核心问题是OnClientClick属性用双引号作为边界,内部Eval("id")的双引号会被ASP.NET解析器判定为属性提前闭合,导致语法错误。
解决方法
方法1:前端调整引号嵌套(无需后台代码)
ASP.NET允许服务器控件的属性值用单引号包裹,直接把OnClientClick的外层双引号换成单引号,内部绑定表达式正常使用双引号即可,根据id的类型选择对应写法:
- 如果id是数值类型,不需要给参数加引号:
<asp:ImageButton ID="imgbut" runat="server" src="/images/gimage.jpg" OnClientClick='<%# string.Format("display({0})", Eval("id")) %>' />
- 如果id是字符串类型,需要给参数补单引号,注意和外层的属性单引号区分:
<asp:ImageButton ID="imgbut" runat="server" src="/images/gimage.jpg" OnClientClick='<%# string.Format("display('{0}')", Eval("id")) %>' />
如果id值可能包含单引号等特殊字符,建议在绑定时调用替换方法转义,避免JS语法错误。
方法2:GridView行绑定事件后台赋值(最稳定,无语法坑)
不想处理前端引号冲突的话,直接在RowDataBound事件里给按钮动态赋值OnClientClick属性,完全避开前端标记解析问题,还能统一做参数转义,是生产环境常用方案。
首先给GridView配置行绑定事件,ImageButton去掉OnClientClick属性:
<asp:GridView ID="gvData" runat="server" DataSourceID="ObjectDataSource1" OnRowDataBound="gvData_RowDataBound"> <Columns> <asp:TemplateField> <ItemTemplate> <asp:ImageButton ID="imgbut" runat="server" src="/images/gimage.jpg" /> </ItemTemplate> </asp:TemplateField> <!-- 其余列配置保持不变 --> </Columns> </asp:GridView>
后台对应事件代码:
protected void gvData_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { var btn = (ImageButton)e.Row.FindControl("imgbut"); string id = DataBinder.Eval(e.Row.DataItem, "id").ToString(); // 转义单引号避免JS报错,加return false可阻止按钮默认回发,不需要可以删掉 btn.OnClientClick = $"display('{id.Replace("'", "\\'")}');return false;"; } }
内容的提问来源于stack exchange,提问作者Kemal AL GAZZAH
相关产品推荐
相关产品推荐

