MVC 从两个模型创建中获取数据

本文关键字:创建 模型 获取 数据 两个 MVC | 更新日期: 2023-09-27 18:36:57

所以是的,我试图为我的"产品"制作一个创建视图,而我使用集合模型在同一视图中同时获得产品和客户。我真正知道如何获得值的唯一方法是做一个foreach,但这在这里并不真正有效:P我找到的唯一搜索是人们说使用 model => model.product.Name 等,但这对我不起作用,也许我错过了什么?

我要做的是,我想将产品添加到下拉列表中选择的客户。这段代码是否足够,或者我需要记住什么?

编辑忘了说我试图像@Html.EditorFor(model => model.product.Name)那样做,但是一个工作,并且可以很好地处理创建:s

@model Co56_Invoice_.Models.Collection
<h2>Skapa ny produkt</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
    <div class="form-horizontal">
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            <div class="col-md-10">
                @Html.DropDownList("Kunder",
          Model.customer.Select(x => new SelectListItem()
          { Text = x.Name.ToString(), Value = x.CustomerID.ToString() }).ToList()
          , "Välj kund")
            </div>
        </div>


    </div>
    }
 <div>
     @Html.ActionLink("Back to List", "Index")
 </div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

public ActionResult Create()
    {
        col.customer = (from o in db.Customers select o).ToList();
        col.product = (from o in db.Products select o).ToList();
        return View(col);
    }
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "CustomerID,ProductID,Name,StartDate,Interval,Price,YearPrice,TotalPrice,Category,Paid")] Product product)
    {
        try
        {
            if (ModelState.IsValid)
            {
                db.Products.Add(product);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
        }
        catch(Exception e)
        {
            throw e.InnerException;
        }
        return View(product);
    }

MVC 从两个模型创建中获取数据

在你的视图中,你应该使用Using application.models.ViewModelName,然后在你的foreach

 @foreach(model1 in Model) { }
 @foreach(model2 in Model) { }

我会建议对你的方法进行一些更改。

首先,如果产品是你正在创建的,那么它应该是视图中的模型和你的两个创建方法(包括HTTP POST)。 *刚刚意识到@Stephen穆克指出了这一点。

要解决将列表和其他所需数据传递到视图中的问题,请广泛使用 ViewBag。 此外,您需要预先选择所有下拉项。

因此,您的操作方法应如下所示:

public ActionResult Create()
    {
        ViewBag.CustomerList =
            db.Customers
            .Select(x => new SelectListItem { Text = x.Name.ToString(), Value = x.CustomerID.ToString() })
            .ToList();
        ViewBag.ProductList = db.Products
            .Select(x => new SelectListItem { Text = x.Name.ToString(), Value = x.CustomerID.ToString() })
            .ToList();
        var m = new Product();
        /*
         do some initialization on the Product object if required.
         better still, use a factory method to create new instance of Product.
        */
        return View(m);
    }
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "CustomerID,ProductID,Name,StartDate,Interval,Price,YearPrice,TotalPrice,Category,Paid")] Product product)
    {
        try
        {
            if (ModelState.IsValid)
            {
                /*
                Use some helper method(s) to carry out extra validation on your model; unless it's all done unobtrusively with Validation Attributes
                */
                db.Products.Add(product);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
        }
        catch (Exception e)
        {
            throw e.InnerException;
        }
        return View(product);
    }

然后,您的视图可能如下所示:

@model Product
<h2>Skapa ny produkt</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
    <div class="form-horizontal">
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            <div class="col-md-10">
                @Html.DropDownListFor(m => m.ProductId, (ViewBag.CustomerList as IEnumerable<SelectListItem>), "Välj kund")
            </div>
        </div>
        <!--Other fields can be included-->
    </div>
    }
 <div>
     @Html.ActionLink("Back to List", "Index")
 </div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}