使用按钮从视图内部调用 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 操作

MVC:编辑操作未调用编辑视图

当内部按钮触摸时,如何从 Superview 中删除以编程方式创建的子视图?

如何从 ListItem 内部调用按钮?

Swift 从按钮内部、弹出框和单元格以编程方式在地图顶部打开一个新的视图控制器

Django - 从模板内部调用带有表单的视图