如何在视图中使用ViewModel更新列表?将数据从视图传递到控制器

时间:2019-03-26 17:08:54

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

我正在传递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; }
    }

Create.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));
        }

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

2 个答案:

答案 0 :(得分:0)

我让您的示例可以在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>

答案 1 :(得分:0)

@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);
    }