使用按钮从视图内部调用 httppost actionresult
Posted
技术标签:
【中文标题】使用按钮从视图内部调用 httppost actionresult【英文标题】:Calling httppost actionresult from inside a view using a button 【发布时间】:2015-12-18 22:38:36 【问题描述】:我有一个项目要使用数据库在用户之间建立网上商店(发布产品、购买等)。在这个项目中,我有一个名为“ShoppingCart”的视图:
@model IEnumerable<MyFirstProject.Models.Product>
@
ViewBag.Title = "ShoppingCart";
Layout = "~/Views/Shared/_Layout.cshtml";
<h2>Your Shopping Cart</h2>
@if (Model == null)
<div style="float:left">Your cart is empty.</div>
<div>
Total payment: 0
</div>
else
decimal tPrice = 0;
<div>
<table style="float:left">
@foreach (var product in Model)
tPrice = tPrice + product.Price;
Html.RenderPartial("ProductLine", product);
</table>
</div>
<div>
Total payment: @tPrice
</div>
它接收用户决定购买的产品列表并显示它们(不是重要部分)。我需要添加一个按钮,它将列表发送到“ShoppingController”中的操作结果:
[HttpPost]
public ActionResult ShoppingCart(List<Product> bought)
if (ModelState.IsValid)
foreach (var listP in bought.ToList())
foreach (var databaseP in db.Products.ToList())
if (listP.ProductID == databaseP.ProductID)
databaseP.State = 1;
db.SaveChanges();
break;
return RedirectToAction("Index");
else
return View(bought);
“状态”表示产品是否已购买(0=未购买,1=已购买),db为数据库
【问题讨论】:
你没有。 (您需要为您查看的每个产品的每个属性包含一个表单控件)。如果这是一个确认页面,那么您只需发布一个 ID 值,然后检索用户已经选择的产品集合并从您之前存储它的存储库中检索它(我假设您使用Session
?)
【参考方案1】:
如果您不想将任何数据从视图发布到操作方法,则应将该数据保存在表单元素中并将其保存在表单中。由于您想发布项目集合,您可以使用Editor Templates。
让我们从创建一个视图模型开始。
public class ShoppingCartViewModel
public decimal TotalPrice set; get;
public List<Product> CartItems set; get;
public class Product
public int Id set; get;
public string Name set; get;
现在在您的 GET 操作中,您将创建一个 ShoppingCartViewModel
的对象,加载 CartItems
属性并发送到视图。
public ActionResult Index()
var cart = new ShoppingCartViewModel
CartItems = new List<Product>
new Product Id = 1, Name = "Iphone" ,
new Product Id = 3, Name = "MacBookPro"
,
TotalPrice = 3234.95
;
return View(cart);
现在我将创建一个 EditorTemplate。为此,请转到您的 ~/Views/YourControllerName
文件夹,并创建一个名为 EditorTemplates
的目录并添加一个名为 Product.cshtml
的视图
文件名应与类型名匹配。
打开这个新视图并添加以下代码。
@model YourNamespace.Product
<div>
<h4>@Model.Name</h4>
@Html.HiddenFor(s=>s.Id)
</div>
您可以随意保留显示。但重要的是,我们需要为 productId 保留一个表单字段。我们将其保存在此处的隐藏字段中。
现在让我们回到我们的主视图。我们需要将此视图强类型化到我们的ShoppingCartViewModel
。我们将在这个视图中使用EditorFor
html helper 方法来调用我们的编辑器模板
@model ReplaceYourNamespaceHere.ShoppingCartViewModel
@using (Html.BeginForm())
@Html.EditorFor(x => x.CartItems)
<p>Total : @Model.TotalPrice</p>
<input type="submit" />
在您的 HttpPost 操作方法中,我们将有一个 ShoppingCartViewModel
类型的参数。提交表单时,MVC 模型绑定器会将发布的表单值映射到 ShoppingCartViewModel
的对象。
[HttpPost]
public ActionResult Index(ShoppingCartViewModel model)
foreach (var item in model.CartItems)
var productId = item.Id;
// to do : Use productId and do something
return RedirectToAction("OrderSucessful");
您可以遍历 CartItems
集合并获取产品的 Id 并做任何您想做的事情。
如果您不允许用户编辑此页面中的项目(使用复选框),请查看this answer。基本上是一样的,但是你在 Product 类中添加了一个布尔属性并使用它来渲染一个复选框。
【讨论】:
以上是关于使用按钮从视图内部调用 httppost actionresult的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET JQuery,禁用表单提交按钮不调用 httpPost 操作
当内部按钮触摸时,如何从 Superview 中删除以编程方式创建的子视图?