ASP.NET MVC Razor向List添加元素报id不存在的解决方法
错误原因
你混淆了Razor服务端代码和JavaScript客户端代码的执行时机:
- 所有带
@前缀的Razor代码是服务端执行逻辑:在页面被发送到用户浏览器之前,就已经在服务器上跑完了,执行的时候根本拿不到用户浏览器里后续才产生的JS变量。 - 你写的
RemoveJS函数是客户端执行逻辑:只有用户点击页面上的X按钮时,才会在用户的浏览器里运行,这时候服务端的Razor代码早就执行结束了。
你写的@deletedImages.Add(id)是服务端代码,服务端渲染阶段完全感知不到客户端JS里的id参数(这个id是用户点击时才传入的动态值),自然会抛出「当前上下文中不存在名称id」的错误。
另外你原来的锚点写法还有个隐藏问题:如果@item是字符串类型,渲染后传给JS的参数没有引号包裹,会直接被JS识别成未定义变量,触发前端报错。
修复方案
根据你的业务场景二选一即可:
方案1:前端暂存,提交表单时统一传值(推荐,无额外请求)
如果不需要点击X就立刻通知后端,只需要在最终提交表单时把所有要删除的图片ID传给后端,直接用前端数组维护删除列表即可,不需要在Razor里声明服务端的deletedImages变量:
- 修正锚点标签,给
@item参数加单引号包裹:
<a href="javascript:void(0)" onclick="Remove('@item', this)">X</a>
- 改写JS逻辑,用前端数组存储待删除ID:
<script> // 前端维护待删除ID列表 const deletedImages = []; function Remove(id, e) { // 把当前ID加入待删除列表 deletedImages.push(id); // 补充你的UI交互逻辑,比如隐藏对应图片项 e.closest('.img-container').style.display = 'none'; } // 最终提交表单的时候,把deletedImages数组传给后端即可 // 可以放到隐藏表单域,或者通过AJAX提交时作为参数传递 </script>
方案2:点击时实时通知后端
如果需要点击X就立刻让后端记录待删除ID,不要在JS里直接写Razor代码,改成发异步请求到后端接口:
- 后端编写接收删除ID的接口,把ID存在服务端可持久化的位置(比如Session、缓存、数据库,注意原来Razor里声明的
List<string>是请求级别的,页面渲染完就销毁了,根本存不住跨请求的数据):
[HttpPost] public ActionResult RecordDeleteImage(string imageId) { // 示例:存在Session里,你可以根据自己的需求换存储位置 var deletedList = Session["DeletedImages"] as List<string> ?? new List<string>(); deletedList.Add(imageId); Session["DeletedImages"] = deletedList; return Json(new { ok = true }); }
- 锚点标签同样按照方案1修正参数引号,然后改写JS函数发异步请求:
<script> function Remove(id, e) { // 发POST请求通知后端记录删除ID fetch('/你的控制器名/RecordDeleteImage', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `imageId=${encodeURIComponent(id)}` }).then(res => res.json()).then(res => { if (res.ok) { // 请求成功再更新UI e.closest('.img-container').remove(); } }) } </script>
内容的提问来源于stack exchange,提问作者ELOL
相关产品推荐
相关产品推荐

