ASP.Net MVC:如何构建按钮调用控制器中的函数?
解决ASP.NET中“购买”按钮添加商品到购物车并跳转的问题
看起来你踩了服务器端代码和客户端代码混用的坑,我来帮你梳理问题并给出最佳实现方式:
先分析你遇到的两个问题
- 第一个方案(input button加href):
<input type="button">本身不支持href属性,所以点击它不会触发跳转,自然没反应。 - 第二个方案(@Html.ActionLink):
@Html.ActionLink是服务器端 Razor 代码,在页面渲染前就会执行;而document.getElementById('Amound').value是客户端 JavaScript 代码,只有页面加载到浏览器后才会运行。服务器端根本不知道document是什么,所以会报CS0103错误。
最佳实现方式推荐
方案1:使用表单提交(简单直接,无需JS)
这种方式利用HTML表单将商品ID和数量提交到控制器,是最传统也最可靠的方式:
修改你的视图代码,把数量输入和按钮放到一个表单里:
@{ ViewBag.Title = "Details"; } <h2>Details</h2> <div> <h4>Prod</h4> <hr /> <dl class="dl-horizontal"> <dt> @Html.DisplayNameFor(model => model.Nazwa) </dt> <dd> @Html.DisplayFor(model => model.Nazwa) </dd> <dt> @Html.DisplayNameFor(model => model.Cena) </dt> <dd> @Html.DisplayFor(model => model.Cena) </dd> <dt> @Html.DisplayNameFor(model => model.Waga) </dt> <dd> @Html.DisplayFor(model => model.Waga) </dd> <dt> @Html.DisplayNameFor(model => model.Kategoria) </dt> <dd> @Html.DisplayFor(model => model.Kategoria) </dd> <dt> @Html.DisplayNameFor(model => model.Il_Dost) </dt> <dd> @Html.DisplayFor(model => model.Il_Dost) </dd> </dl> <!-- 新增表单 --> @using (Html.BeginForm("DodajDoKoszyka", "Prods", FormMethod.Post)) { @Html.HiddenFor(model => model.ID) <!-- 传递商品ID --> <div class="input-group"> <input type="number" class="form-control" min="1" max="@Model.Il_Dost" id="Amound" name="ilosc" required> <button type="submit" class="btn btn-primary">Kup</button> </div> } </div> <p> @Html.ActionLink("Back to List", "Index") </p>
然后确保你的控制器DodajDoKoszyka方法支持POST请求(默认是GET,需要加[HttpPost]特性):
[HttpPost] public ActionResult DodajDoKoszyka(int id, int ilosc) { Zamawiany Z = new Zamawiany(); Prod P = ProductBuId(id); // 这里不用Convert.ToInt32,因为id已经是int了 Z.Id = id; Z.Ilosc = ilosc; Z.Waga = Convert.ToInt32(P.Waga); Z.Cena = Convert.ToInt32(P.Cena); Koszyk.Instance.WKoszyku.Add(Z); return ViewBasket(); // 跳转到购物车页面 }
优点:
- 不需要写JavaScript,对新手友好
- 天然支持表单验证(比如
required属性确保数量不为空,min/max限制输入范围) - 符合HTTP规范,POST请求用于修改数据(添加购物车属于修改操作)
方案2:使用JavaScript处理点击事件(更灵活)
如果你想要更灵活的交互(比如点击前验证数量,或者异步添加后再跳转),可以用JS来处理:
修改视图中的按钮部分:
<div class="input-group"> <input type="number" class="form-control" min="1" max="@Model.Il_Dost" id="Amound" required> <button type="button" class="btn btn-primary" onclick="addToCart()">Kup</button> </div> <!-- 新增JS代码 --> <script> function addToCart() { const productId = @Model.ID; // 服务器端渲染商品ID const quantity = document.getElementById('Amound').value; // 简单验证数量 if (quantity < 1 || quantity > @Model.Il_Dost) { alert("请输入有效的购买数量!"); return; } // 跳转到控制器方法,传递参数 window.location.href = '@Url.Action("DodajDoKoszyka", "Prods")' + `?id=${productId}&ilosc=${quantity}`; } </script>
控制器方法可以保持原来的(如果是GET请求的话),但更推荐用POST,所以可以稍微调整:
public ActionResult DodajDoKoszyka(int id, int ilosc) { // 你的原有代码... return ViewBasket(); }
优点:
- 可以添加自定义验证逻辑(比如提示用户数量无效)
- 支持异步操作(比如用AJAX添加到购物车,然后再跳转,用户体验更好)
额外提醒
你用的Koszyk.Instance是单例类,这在多用户场景下会有问题——所有用户的购物车数据会共享!如果是正式项目,建议改用Session或者数据库来存储购物车信息,比如:
// 改用Session存储购物车 List<Zamawiany> cart = Session["Cart"] as List<Zamawiany> ?? new List<Zamawiany>(); cart.Add(Z); Session["Cart"] = cart;
这样每个用户的购物车数据都是独立的,不会互相干扰。
内容的提问来源于stack exchange,提问作者JaegerAurora
相关产品推荐
相关产品推荐

