Вызов httppost actionresult из представления с помощью кнопки

У меня есть проект по созданию интернет-магазина между пользователями (размещение продукта, покупка и т. д.) с использованием базы данных. В этом проекте у меня есть представление под названием «Корзина покупок»:

@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 — это база данных.


person Alon Heilig    schedule 18.12.2015    source источник
comment
Вы не знаете. (вам нужно будет включить элемент управления формой для каждого свойства каждого продукта в вашем представлении). Если это страница подтверждения, то вы просто публикуете значение идентификатора, а затем извлекаете коллекцию продуктов, которую пользователь уже выбрал, и извлекаете ее из репозитория, который вы ранее сохранили (я полагаю, вы использовали Session?)   -  person    schedule 19.12.2015


Ответы (1)


Если вы не хотите отправлять какие-либо данные из представления в метод действия, вы должны хранить эти данные в элементах формы и хранить их в форме. Поскольку вы хотите опубликовать коллекцию элементов, вы можете использовать шаблоны редактора.

Начнем с создания модели представления.

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. В этом представлении мы будем использовать вспомогательный метод html EditorFor для вызова нашего шаблона редактора.

@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, получить идентификатор продуктов и делать все, что хотите.

введите здесь описание изображения

Если вы не хотите разрешать пользователю редактировать элементы (с помощью флажка) на этой странице, взгляните на этот ответ. Это в основном то же самое, но вы добавляете логическое свойство в класс Product и используете его для рендеринга флажка.

person Shyju    schedule 19.12.2015