asp.net-mvc MVC5 添加项目到列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20027021/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 03:20:09  来源:igfitidea点击:

MVC5 Add Item to List

asp.net-mvcrazorasp.net-mvc-5

提问by Wjdavis5

Given a Model of :

给定一个模型:

public class Receipt: BaseEntity
{
    [Required(AllowEmptyStrings = false,ErrorMessage = "Please Select A Store")]
    public Store  Store { get; set; }
    public List<Item> Items { get; set; }
    public Item NewItem { get; private set; }
    [Required(AllowEmptyStrings = false,ErrorMessage = "ReceiptModel.EntryDate is required")]
    public DateTime EntryDate { get; set; }
    public Guid EntryOwner { get; set; }
    public string Name { get; set; }

    public double ReceiptTotal()
    {
        return Items.Sum(item => item.ItemPrice);
    }
    public Receipt()
    {
        Items = new List<Item>();
        EntryOwner = Guid.Empty;
        EntryDate = DateTime.Now;
        Store = new Store();
        NewItem = new Item();
     }       
}

And a Controller :

和一个控制器:

public class ReceiptController : Controller
{
    //
    // GET: /Receipt/

    public ActionResult Index()
    {
        Receipt receipt = new Receipt();
        return View(receipt);
    }

    [HttpPost]
    public ActionResult AddItem(Receipt receipt)
    {
        receipt.Items.Add(receipt.NewItem);
        if (ModelState.IsValid)
        {
            return View("Index", receipt);
        }
        return View("Index", receipt);
    }

And a View: Updated View - Removed all partial pages and combined into a single page

和一个视图:更新视图 - 删除所有部分页面并合并为一个页面

<form class="form-horizontal" method="POST" action="@Url.Action("AddItem","Receipt")">
<div class="jumbotron">
    <div id="main" class="panel panel-primary">

        <div class="panel-heading"> <h1 class="panel-title">Receipt Builder</h1></div>
        <div class="panel-body">

            <fieldset>
                @Html.LabelFor(model => model.Name)
                @Html.EditorFor(model => model.Name)

                @Html.LabelFor(model => model.Store.Name)
                @Html.EditorFor(model => model.Store.Name)

                @Html.LabelFor(model => model.EntryDate)
                @Html.EditorFor(model => model.EntryDate)
            </fieldset>

        </div>


    </div>
</div>

<table class="table table-bordered table-condensed table-hover table-responsive table-striped">
    <thead>
        <tr>
            <td>
                <label class="control-label">#</label>
            </td>
            <td>
                <label class="control-label">Item</label>
            </td>
            <td>
                <label class="control-label">Unit</label>
            </td>
            <td>
                <label class="control-label">Quantity</label>
            </td>
            <td>
                <label class="control-label">UnitPrice</label>
            </td>
            <td>
                <label class="control-label">Category</label>
            </td>
            <td>
                <label class="control-label">Total</label>
            </td>
        </tr>
        <tr>

                <td>
                    <button class="btn-sm btn-danger" style="border-radius: 50%; background-color: red;" name="Submit" id="Submit" type="submit">+</button>
                </td>

                <td>
                    @Html.EditorFor(model => model.NewItem.Name)
                </td>

                <td>
                    @Html.EditorFor(model => model.NewItem.UnitType)
                </td>

                <td>
                    @Html.EditorFor(model => model.NewItem.Quantity)
                </td>

                <td>
                    @Html.EditorFor(model => model.NewItem.UnitPrice)
                </td>

                <td>
                    @Html.EditorFor(model => model.NewItem.Category.Name)<br/>
                    @Html.EditorFor(model => model.NewItem.Category.IsTaxable)
                </td>

                <td>
                    @Html.EditorFor(model => model.NewItem.ItemPrice)
                </td>


        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Items)
        {
            <tr>
                <td>
                    @Model.Items.ToList().IndexOf(item) + 1
                </td>
                <td>
                    @Html.LabelFor(titem => item.Name)
                </td>
                <td>
                    @Html.LabelFor(titem => item.UnitType)
                </td>
                <td>
                    @Html.LabelFor(titem => item.Quantity)
                </td>
                <td>
                    @Html.LabelFor(titem => item.UnitPrice)
                </td>
                <td>
                    @Html.LabelFor(titem => item.Category.Name)
                </td>
                <td>
                    @Html.LabelFor(titem => item.ItemPrice)
                </td>
            </tr>
        }
    </tbody>

    <tfoot></tfoot>
</table>

回答by Wjdavis5

I was finally able to resolve this thanks to This Link

多亏了这个链接,我终于能够解决这个问题

It was indeed a binding issue as was suggested. It seems that with complex collections such as Lists we cannot actually utilize the benefits of IEnumerable like I had hoped. This is due to how the data is actually passed in the post having names that are ambiguous. Here is the final code that is working (only have to update the view)

正如所建议的那样,这确实是一个具有约束力的问题。似乎对于像 List 这样的复杂集合,我们实际上无法像我希望的那样利用 IEnumerable 的好处。这是由于数据在具有不明确名称的帖子中实际传递的方式。这是正在运行的最终代码(只需更新视图)

 @for (int i = 0; i < Model.Items.Count(); i++)
        {
            <tr>
                <td>
                @(i+1)
                </td>
                <td>
                    @Html.TextBoxFor(m => m.Items[i].Name)
                </td>
                <td>
                    @Html.TextBoxFor(m => m.Items[i].UnitType)
                </td>
                <td>
                    @Html.TextBoxFor(m => m.Items[i].Quantity)
                </td>
                <td>
                    @Html.TextBoxFor(m => m.Items[i].UnitPrice)
                </td>
                <td>
                    @Html.TextBoxFor(m => m.Items[i].Category.Name)
                </td>
                <td>
                    @Model.Items[i].ItemPrice
                </td>
            </tr>
        }

The resulting HTML names each element with its index ie Item[N].Name Now the post data can be bound correctly.

生成的 HTML 用其索引命名每个元素,即 Item[N].Name 现在可以正确绑定发布数据。

回答by Dmytro Rudenko

Items from your Receipt are shows just as text, without controls. So when you post data back to server ASP.NET MVC can't find this information from request body and lefts Receipt.Items collection empty.

收据中的项目仅显示为文本,没有控件。因此,当您将数据发回服务器时,ASP.NET MVC 无法从请求正文中找到此信息,并将 Receipt.Items 集合留空。

You may add information about entered receipts as hidden fields in partial view with help of Html.HiddenFor() method. Or just save entered items in DB or somewhere else and read theirs into Receipt.Items collection before returning AddItem view.

您可以在 Html.HiddenFor() 方法的帮助下,将有关输入收据的信息添加为部分视图中的隐藏字段。或者只是将输入的项目保存在 DB 或其他地方,然后在返回 AddItem 视图之前将它们读入 Receipt.Items 集合。