【问题标题】:How to update list withing viewmodel in view? Passing data from view to controller如何在视图中更新视图模型中的列表?将数据从视图传递到控制器
【发布时间】:2019-03-26 17:08:53
【问题描述】:

我传递 viewmodel 来创建视图,我从下拉列表中选择几个属性,然后在数据库中创建新模型。问题是我必须从下拉列表中选择一个产品,然后单击按钮将产品添加到列表(在模型中定义)。您可以看到下面的代码,我遇到了传递产品 id 的问题,因为它始终为 null

SellsViewModel:

public class SellsViewModel
    {
        public List<Center> center { get; set; }
        public List<Leader> leader { get; set; }
        public List<Member> member { get; set; }
        public List<Group> group { get; set; }
        public Sell sell { get; set; }
        public Guid productSelection { get; set; }
        public IEnumerable<Product> product { get; set; }
        public IEnumerable<Product> selectedProducts { get; set; }
    }

创建.cshtml

@model Medical.ViewModels.SellsViewModel

@{
    var addproduct = Model.product.Select(product => new SelectListItem
    {
        Text = product.Name,
        Value = product.Id.ToString()
    });
}
...
<div class="form-group">
                <div align="right" class="col-md-2">
                    <b>Delivery</b>
                </div>
                <div align="center" class="col-md-2">
                    @Html.DropDownListFor(m => m.productSelection, addproduct, "-- Choose product --")
                </div>
                <div class="col-md-2">
                    <a asp-action="AddProducttoSell" method="post" asp-route-id="@Model.productSelection" class="btn btn-primary">Add</a>
                </div>
            </div>

控制器:

[HttpGet]
        public IActionResult AddProducttoSell(Guid id)
        {
            var sProduct = _context.Products.FirstOrDefault(p => p.Id == id);
            svm.selectedProducts.ToList().Add(sProduct);
            return RedirectToAction(nameof(Create));
        }

基本上,我希望当我在视图中选择产品时,将其添加到视图模型中的 selectedProducts 列表中,然后将其返回到视图中。之后,我会将新模型提交到数据库。

【问题讨论】:

  • asp-route-id="@Model.productSelection" 在渲染时间之前完成,并且绝对在用户选择 ddl 之前完成。你把值放在一个 foreach 循环中——比如行。

标签: asp.net-mvc asp.net-core model-view-controller


【解决方案1】:

我让你的例子在 Core 中工作。

首先,我按照本教程进行了适当的更改:

https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/intro?view=aspnetcore-2.2

这是代码,从我的 Model-codeFirst 和我的 ViewModel 开始:

namespace SOPassDataViewToController.Models
{
    public class Sell
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }
}

namespace SOPassDataViewToController.Models
{
    public class Product
    {
        public int Value { get; set; }
        public string Text { get; set; }
    }

    public class SellsViewModel
    {
        public List<Product> Products { get; set; }
        public int productSelection { get; set; }
    }
}

这是我的控制器代码:

[HttpPost]
public IActionResult AddProducttoSell(SellsViewModel sellsviewmodel)
{
    //put breakpoint here to interrogate sellsviewmodel-productSelection
    var viewModel = PrepViewModel();
    return View(viewModel);
}

// GET: Sells
// I'm using this method instead of AddProducttoSell
//public async Task<IActionResult> Index()
public IActionResult Index()
{
    var viewModel = PrepViewModel();
    //return View(await _context.Sells.ToListAsync());
    return View(viewModel);
}

public SellsViewModel PrepViewModel()
{
    //prepping view model
    //sending view model to view
    SellsViewModel viewModel = new SellsViewModel();
    viewModel.Products = new List<Product>();
    var products = _context.Sells.ToList();
    foreach (Sell product in products)
    {
        var eachProduct = new Product();
        eachProduct.Value = product.ID;
        eachProduct.Text = product.Name;
        viewModel.Products.Add(eachProduct);
    }
    return viewModel;
}

这是我的观点Index.cshtml:

@model SOPassDataViewToController.Models.SellsViewModel
@*need the form tag*@
<form asp-action="AddProducttoSell">
    <div class="form-group">
        <div align="right" class="col-md-2">
            <b>Delivery</b>
        </div>
        <div align="center" class="col-md-2">
            @*@Html.DropDownListFor(m => m.productSelection, addproduct, "-- Choose product --")*@
            @Html.DropDownListFor(m => m.productSelection, new SelectList(Model.Products, "Value", "Text"))
        </div>
        <div class="col-md-2">
            @*took out will need to put back asp-route-id="@Model.productSelection"*@
            @*<a asp-action="AddProducttoSell" method="post" asp-route-id="@Model.productSelection" class="btn btn-primary">Add</a>*@
            <div class="form-group">
                <input type="submit" value="AddProducttoSell" class="btn btn-primary" />
            </div>
        </div>
    </div>
</form>

【讨论】:

    【解决方案2】:
    @section scripts
        {
        @*//the natural progression for what you are doing is to change the href not the asp-route-id, because
            //href is what gets rendered.  So you can do the following--and tighten it up--
            //you can also use FormCollection, or even possibly window.location, but the best way from Microsoft's
            //tutorial is to use a model like my previous post*@
        <script>
            $(document).ready(function () {
                $("#DropDownElement").change(function () {
                    $("#PostingElement").attr("href", "/Sells/Edit/" + $("#DropDownElement").val());
                })
            });
        </script>
    }
    

    我的操作如下所示。我使用 Edit 而不是 AddProducttoSell

        // GET: Sells/Edit/5
        public async Task<IActionResult> Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }
    
            var sell = await _context.Sells.FindAsync(id);
            if (sell == null)
            {
                return NotFound();
            }
            return View(sell);
        }
    

    【讨论】:

    • 感谢您的回答@kblau。但是,我觉得这有点令人困惑。从索引视图我想打开创建表单。要创建表单,我通过 SellsViewModel 如上所述。在创建表单中,我为 sell model 提供了不同输入的字段。除了输入字段之外,我还有从中选择产品的下拉列表,当我单击“添加”按钮时,我想更新也显示在创建视图中的表并将所选产品添加到所选产品的 sellsviewmodel 列表中。完成表格后,我将表格提交给 sell model,并将 viewmodel 中的选定产品添加到销售中。
    • 我目前的想法是,我希望主视图带有创建表单,部分视图 _create 带有下拉列表和更新的表格。我使用@html.partial 渲染部分视图以查看,并尝试使用return partialview("_Create") 将数据从控制器传递回视图。我只想刷新部分视图,而主视图保持不变。但是,我的 return partialview 会刷新整个页面并仅返回 _Create 视图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-06
    • 2019-09-03
    • 1970-01-01
    • 2012-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多