ASP.NET向JavaScript传值问题:Google Maps API开发遇变量i错误
解决ASP.NET中服务器端控件与客户端JS传值的循环报错问题
嘿,这个问题我太熟了!你遇到的是服务器端代码和客户端JavaScript执行顺序不匹配的坑,我来给你拆解清楚并解决~
问题根源
你写的代码里,<%= ListBoxRX1.Items[i] %>属于服务器端代码,它是在页面发送到浏览器之前就执行完毕的;而JS里的var i是客户端运行时的变量,服务器根本看不到这个i的存在。所以服务器执行到ListBoxRX1.Items[i]时,会认为i是一个未定义的服务器端变量,直接抛出“名称‘i’在当前上下文中不存在”的错误。
简单说:服务器先跑你的ASP.NET代码,再把生成的HTML/JS发给浏览器,JS的循环是在浏览器里才执行的,两者完全不在一个时间线!
解决方案:先把服务器端数据转成JS数组
正确的做法是先把ListBox里的所有数据一次性序列化为JS数组,再在客户端循环使用,而不是在JS循环里混写服务器端代码。下面给两种常用场景的实现方式:
场景1:ASP.NET Web Forms(后台代码)
在后台代码(比如.aspx.cs)里,把ListBox的项转成JSON字符串,然后注册到客户端脚本中:
using Newtonsoft.Json; // 需要先安装Newtonsoft.Json NuGet包 protected void Page_Load(object sender, EventArgs e) { // 把ListBoxRX1的所有项值转成字符串列表 var rx1Values = new List<string>(); foreach (ListItem item in ListBoxRX1.Items) { rx1Values.Add(item.Value); } // 序列化为JSON字符串 string rx1Json = JsonConvert.SerializeObject(rx1Values); // 注册到客户端,生成全局JS变量 ClientScript.RegisterStartupScript(this.GetType(), "RX1Data", $"var RX1 = {rx1Json};", true); // 同理处理RY1、RX2、RY2 var ry1Values = new List<string>(); foreach (ListItem item in ListBoxRY1.Items) { ry1Values.Add(item.Value); } string ry1Json = JsonConvert.SerializeObject(ry1Values); ClientScript.RegisterStartupScript(this.GetType(), "RY1Data", $"var RY1 = {ry1Json};", true); var rx2Values = new List<string>(); foreach (ListItem item in ListBoxRX2.Items) { rx2Values.Add(item.Value); } string rx2Json = JsonConvert.SerializeObject(rx2Values); ClientScript.RegisterStartupScript(this.GetType(), "RX2Data", $"var RX2 = {rx2Json};", true); var ry2Values = new List<string>(); foreach (ListItem item in ListBoxRY2.Items) { ry2Values.Add(item.Value); } string ry2Json = JsonConvert.SerializeObject(ry2Values); ClientScript.RegisterStartupScript(this.GetType(), "RY2Data", $"var RY2 = {ry2Json};", true); }
然后前台JS里直接使用这些数组即可,不需要再写服务器端代码:
// 现在RX1、RY1等已经是客户端数组了 try { for (var i = 0; i < RX1.length; i++) { // 这里可以直接用RX1[i]、RY1[i]等做你需要的操作 console.log(RX1[i], RY1[i], RX2[i], RY2[i]); } } catch (e) { alert("MSSQL 403 Hatası !! Forbidden."); }
场景2:ASP.NET MVC(Razor视图)
如果是MVC项目,可以在控制器里把数据转成JSON,通过ViewBag传递到视图:
using Newtonsoft.Json; public ActionResult YourAction() { var rx1Items = ListBoxRX1.Items.Cast<ListItem>().Select(item => item.Value).ToArray(); ViewBag.RX1Json = JsonConvert.SerializeObject(rx1Items); var ry1Items = ListBoxRY1.Items.Cast<ListItem>().Select(item => item.Value).ToArray(); ViewBag.RY1Json = JsonConvert.SerializeObject(ry1Items); var rx2Items = ListBoxRX2.Items.Cast<ListItem>().Select(item => item.Value).ToArray(); ViewBag.RX2Json = JsonConvert.SerializeObject(rx2Items); var ry2Items = ListBoxRY2.Items.Cast<ListItem>().Select(item => item.Value).ToArray(); ViewBag.RY2Json = JsonConvert.SerializeObject(ry2Items); return View(); }
然后在Razor视图里直接生成JS数组:
var RX1 = @Html.Raw(ViewBag.RX1Json); var RY1 = @Html.Raw(ViewBag.RY1Json); var RX2 = @Html.Raw(ViewBag.RX2Json); var RY2 = @Html.Raw(ViewBag.RY2Json); try { for (var i = 0; i < RX1.length; i++) { // 执行你的业务逻辑 } } catch (e) { alert("MSSQL 403 Hatası !! Forbidden."); }
关键提醒
- 一定要确保ListBox的项数量一致(RX1、RY1、RX2、RY2的长度相同),否则循环时会出现数组越界的问题。
- 如果不需要Newtonsoft.Json,ASP.NET Core也可以用内置的
System.Text.Json来序列化数据,用法类似。
内容的提问来源于stack exchange,提问作者Serkan Kaya
相关产品推荐
相关产品推荐

