将列表作为@Html.Hidden传递,但列表被删除

5

我有一个问题,需要将表单中的列表发送到控制器进行处理和编辑。但是它只破坏了列表,并通过一个空字符串传递。我需要保留列表,以便在控制器中添加内容。

视图如下:

@using (Html.BeginForm("AddToBasket", "Home", FormMethod.Post))
        {
            @Html.Hidden("product", product.Product)
            @Html.Hidden("basketItems", Model.BasketItems)

            <h3>@product.Product (£@product.Price)</h3>
            <div class="menu-item-quantity">
                <h4>Quanitity: @Html.TextBox("quantity", 0, new { @class = "form-control-quantity" })</h4>
            </div>
            <input class="btn btn-lg" type="submit" value="Add to basket" />
        }

控制器:
public ActionResult AddToBasket(string product, int quantity, List<string>basketItems)
        {   
            var products = new GetProductsList<ProductLookup>().Query().ToList();

            var Result = new BuyViewModel
            {
                Products = products,
                BasketItems = basketItems.ToList()
            };

            return View("Buy", Result);
        }

以及模型:

public class BuyViewModel
    {
        public IList<ProductLookup> Products { get; set; }

        public List<string> BasketItems { get; set; }
    }

我该如何将这个列表作为一个整体传递给控制器?

请参见 https://dev59.com/wGcs5IYBdhLWcg3woFbt。 - jao
没问题,我以前也遇到过这个问题 :) 如果下面的代码可用,请告诉我。 - jao
我需要维护列表,以便在控制器中添加内容。不,你绝对不需要(也不应该这样做)。你可以在POST方法中再次从数据库/存储库获取购物篮项目的集合。 - user3559349
@StephenMuecke 你认为应该如何实现呢?这个应用程序需要能够同时处理多个用户。 - rubidge96
@StephenMuecke,我试着按照jao的方法去做,现在已经有一半可以工作了。但是出于好奇,为什么我不应该这样做呢? - rubidge96
显示剩余4条评论
2个回答

6

不是返回一个项目,而是要返回一个列表。

一种方法是返回具有相同名称的表单元素的数组,因此控制器可以将其缝合成一个列表。

这是一个例子:

不是:

@Html.Hidden("basketItems", Model.BasketItems)

添加以下内容:

for (int i = 0; i < Model.BasketItems.Count; i++)
{
    @Html.HiddenFor(m => m.BasketItems[i])
}

这将生成以下HTML代码:
<input type="hidden" name="basketItems[0]" value="item 1" />
<input type="hidden" name="basketItems[1]" value="item 2" />

也许您不需要在@Html中使用@,但我还没有检查过。

更新 我创建了一个测试项目:

TestViewModel.cs

using System;
using System.Collections.Generic;

namespace WebApplication1.Models
{
    public class TestViewModel
    {
        public string Name { get; set; }
        public List<String> Items { get; set; }
    }
}

HomeController.cs

using System.Collections.Generic;
using System.Web.Mvc;
using WebApplication1.Models;

namespace WebApplication1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var viewModel = new TestViewModel {
                Name = "Test name",
                Items = new List<string> { "item 1" , "item 2" }
            };


            return View(viewModel);
        }

        [HttpPost]
        public ActionResult Index(string name, List<string> items)
        {
            var viewModel = new TestViewModel
            {
                Name = name,
                Items = items
            };
            return View(viewModel);
        }

    }
}

Index.cshtml

@model WebApplication1.Models.TestViewModel
@{
    ViewBag.Title = "Home Page";
}

@using (Html.BeginForm("Index", "Home", FormMethod.Post))
{

    for (int i = 0; i < Model.Items.Count; i++)
    {
        @Html.HiddenFor(m => m.Items[i])
    }


    <div class="">
        @Html.TextBoxFor(m => m.Name)
    </div>


    <input type="submit" value="save" />
}

当我点击保存时,表单会再次显示出来,但是现在会显示先前表单中的值。

使用这种方法,当我通过控制器并到达basketItems.Add(product);时会出现错误,因为basketItems为空:/ - rubidge96
你能看到生成的 HTML 中隐藏元素的名称吗? - jao
这是完整源代码:https://wetransfer.com/downloads/d794e626e1dc89238ab18190cefd2f1620180419120404/51a89b,但基本上它是默认的ASP.NET MVC 5项目,并添加了上述代码。 - jao
太好了,听到这个消息很高兴 :) - jao
你有没有想过如何传递一个空列表?显然,当页面第一次加载时,购物篮里什么也没有。 - rubidge96
显示剩余5条评论

0

我很生气,因为这个修复非常简单。我在控制器中添加了一个检查,以便在传递列表为空时做出反应。

[HttpPost]
        public ActionResult Buy(string product, int quantity, List<string>BasketItems)
        {

            var products = new GetProductsList<ProductLookup>().Query().ToList();


            **for (int i = 0; i < quantity; i++)
            {
                if (BasketItems == null)
                {
                    BasketItems = new List<string> { product };
                }
                else
                {
                    BasketItems.Add(product);
                }
            }** 

            var Result = new BuyViewModel
            {
                Products = products,
                BasketItems = BasketItems
            };

            return View("Buy", Result);
        }

我还将视图更改为使用 HiddenFor 而不是 hidden。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接