MVC 6 EF 7 属性 的列表框未填充
Listbox for MVC 6 EF 7 Property not Populating
我已经尝试了一段时间来填充一个列表框,但我似乎无法弄清楚。我已经相当广泛地研究了 entity framework 7 文档,但我仍然是新手。目前还没有很多 MVC6/EF7 的教程,因此很难知道将一个实体 class 与另一个实例相关联的最佳做法是什么。请原谅问题的长度,我只是想彻底。
我正在使用 entity framework 7、asp.net 5 和 MVC 6。
重现问题的步骤
- 创建一个新的ASP.Net Web 应用程序 → 项目名称:ListBox.Web → 解决方案名称列表框
- 选择APS.NET5个模板→Web应用程序
在 Models 文件夹中创建两个 classes
Parent.cs
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace ListBox.Web.Models
{
public class Parent
{
public int ParentId { get; set; }
[Required]
public string Name { get; set; }
public ICollection<Child> Children { get; set; }
}
}
Child.cs
using System.ComponentModel.DataAnnotations;
namespace ListBox.Web.Models
{
public class Child
{
public int ChildId { get; set; }
[Required]
public string Name { get; set; }
public int ParentId { get; set; }
public Parent Parent { get; set; }
}
}
使用脚手架为每个数据 classes 创建控制器和视图
添加指向 _Layout.cshtml
中控制器的链接
<ul class="nav navbar-nav">
<li><a asp-controller="Home" asp-action="Index">Home</a></li>
<li><a asp-controller="Parents" asp-action="Index">Parents</a></li>
<li><a asp-controller="Children" asp-action="Index">Children</a></li>
<li><a asp-controller="Home" asp-action="About">About</a></li>
<li><a asp-controller="Home" asp-action="Contact">Contact</a></li>
</ul>
创建数据库
ListBox\src\ListBox.Web>dns ef migrations add Initial
ListBox\src\ListBox.Web>dnx ef database update
运行 网络应用程序
加一对parents.
尝试添加一个child。
- 显示 parents 的下拉框,但 select
的下拉框中没有项目
- 列表框的HTML是:
<select class="form-control" data-val="true" data-val-required="The ParentId field is required." id="ParentId" name="ParentId"></select>
控制器源代码
using System.Linq;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Data.Entity;
using ListBox.Web.Models;
namespace ListBox.Web.Controllers
{
public class ChildrenController : Controller
{
private ApplicationDbContext _context;
public ChildrenController(ApplicationDbContext context)
{
_context = context;
}
// GET: Children
public IActionResult Index()
{
var applicationDbContext = _context.Child.Include(c => c.Parent);
return View(applicationDbContext.ToList());
}
// GET: Children/Details/5
public IActionResult Details(int? id)
{
if (id == null)
{
return HttpNotFound();
}
Child child = _context.Child.Single(m => m.ChildId == id);
if (child == null)
{
return HttpNotFound();
}
return View(child);
}
// GET: Children/Create
public IActionResult Create()
{
ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent");
return View();
}
// POST: Children/Create
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Child child)
{
if (ModelState.IsValid)
{
_context.Child.Add(child);
_context.SaveChanges();
return RedirectToAction("Index");
}
ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent", child.ParentId);
return View(child);
}
// GET: Children/Edit/5
public IActionResult Edit(int? id)
{
if (id == null)
{
return HttpNotFound();
}
Child child = _context.Child.Single(m => m.ChildId == id);
if (child == null)
{
return HttpNotFound();
}
ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent", child.ParentId);
return View(child);
}
// POST: Children/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Edit(Child child)
{
if (ModelState.IsValid)
{
_context.Update(child);
_context.SaveChanges();
return RedirectToAction("Index");
}
ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent", child.ParentId);
return View(child);
}
// GET: Children/Delete/5
[ActionName("Delete")]
public IActionResult Delete(int? id)
{
if (id == null)
{
return HttpNotFound();
}
Child child = _context.Child.Single(m => m.ChildId == id);
if (child == null)
{
return HttpNotFound();
}
return View(child);
}
// POST: Children/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public IActionResult DeleteConfirmed(int id)
{
Child child = _context.Child.Single(m => m.ChildId == id);
_context.Child.Remove(child);
_context.SaveChanges();
return RedirectToAction("Index");
}
}
}
Child Create.cshtml
@model ListBox.Web.Models.Child
@{
ViewData["Title"] = "Create";
}
<h2>Create</h2>
<form asp-action="Create">
<div class="form-horizontal">
<h4>Child</h4>
<hr />
<div asp-validation-summary="ValidationSummary.ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="ParentId" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="ParentId" class ="form-control"></select>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
</form>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
}
更改ChildrenController
中的Create()
方法,更改
public IActionResult Create()
{
ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent");
return View();
}
到
public IActionResult Create()
{
ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Name");
return View();
}
在Create.cshtml
中,更改
<select asp-for="ParentId" class="form-control"></select>
到
@Html.DropDownList("ParentId", null, htmlAttributes: new { @class = "form-control" })
生成的代码不正确,这是一个错误https://github.com/aspnet/Scaffolding/issues/149
使用 "tag helpers" 的一个解决方案是:
控制器
...
ViewData["Parents"] = new SelectList(_context.Set<Parent>(), "ParentId", "Name", child.ParentId);
...
查看
@{
var parents = (IEnumerable<SelectListItem>)ViewData["Parents"];
}
...
<select asp-for="ParentId" asp-items="parents" class ="form-control">
<option disabled selected>--- SELECT ---</option>
</select>
...
以下是当只有一种类型的对象嵌套在另一个相同类型的对象中时的操作方法。
对象:
public class Fleet
{
public int Id { get; set; }
public Fleet ParentFleet { get; set; }
public int? ParentFleetId { get; set; }
public string Name { get; set; }
[InverseProperty("ParentFleet")]
public virtual List<Fleet> Children { get; set; }
public List<UserFleet> UserFleets { get; set; }
}
控制器:
ViewData["ParentFleetId"] = new SelectList(_context.Set<Fleet>(), "Id", "Name");
return View();
查看:
<form asp-action="Create">
<div class="form-horizontal">
<h4>Fleet</h4>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="ParentFleet" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="ParentFleetId" asp-items="ViewBag.ParentFleetId" class="form-control">
<option value=""></option>
</select>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
</form>
我已经尝试了一段时间来填充一个列表框,但我似乎无法弄清楚。我已经相当广泛地研究了 entity framework 7 文档,但我仍然是新手。目前还没有很多 MVC6/EF7 的教程,因此很难知道将一个实体 class 与另一个实例相关联的最佳做法是什么。请原谅问题的长度,我只是想彻底。
我正在使用 entity framework 7、asp.net 5 和 MVC 6。
重现问题的步骤
- 创建一个新的ASP.Net Web 应用程序 → 项目名称:ListBox.Web → 解决方案名称列表框
- 选择APS.NET5个模板→Web应用程序
在 Models 文件夹中创建两个 classes
Parent.cs
using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace ListBox.Web.Models { public class Parent { public int ParentId { get; set; } [Required] public string Name { get; set; } public ICollection<Child> Children { get; set; } } }
Child.cs
using System.ComponentModel.DataAnnotations; namespace ListBox.Web.Models { public class Child { public int ChildId { get; set; } [Required] public string Name { get; set; } public int ParentId { get; set; } public Parent Parent { get; set; } } }
使用脚手架为每个数据 classes 创建控制器和视图
添加指向
中控制器的链接_Layout.cshtml
<ul class="nav navbar-nav"> <li><a asp-controller="Home" asp-action="Index">Home</a></li> <li><a asp-controller="Parents" asp-action="Index">Parents</a></li> <li><a asp-controller="Children" asp-action="Index">Children</a></li> <li><a asp-controller="Home" asp-action="About">About</a></li> <li><a asp-controller="Home" asp-action="Contact">Contact</a></li> </ul>
创建数据库
ListBox\src\ListBox.Web>dns ef migrations add Initial ListBox\src\ListBox.Web>dnx ef database update
运行 网络应用程序
加一对parents.
尝试添加一个child。
- 显示 parents 的下拉框,但 select 的下拉框中没有项目
- 列表框的HTML是:
<select class="form-control" data-val="true" data-val-required="The ParentId field is required." id="ParentId" name="ParentId"></select>
控制器源代码
using System.Linq;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Data.Entity;
using ListBox.Web.Models;
namespace ListBox.Web.Controllers
{
public class ChildrenController : Controller
{
private ApplicationDbContext _context;
public ChildrenController(ApplicationDbContext context)
{
_context = context;
}
// GET: Children
public IActionResult Index()
{
var applicationDbContext = _context.Child.Include(c => c.Parent);
return View(applicationDbContext.ToList());
}
// GET: Children/Details/5
public IActionResult Details(int? id)
{
if (id == null)
{
return HttpNotFound();
}
Child child = _context.Child.Single(m => m.ChildId == id);
if (child == null)
{
return HttpNotFound();
}
return View(child);
}
// GET: Children/Create
public IActionResult Create()
{
ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent");
return View();
}
// POST: Children/Create
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Child child)
{
if (ModelState.IsValid)
{
_context.Child.Add(child);
_context.SaveChanges();
return RedirectToAction("Index");
}
ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent", child.ParentId);
return View(child);
}
// GET: Children/Edit/5
public IActionResult Edit(int? id)
{
if (id == null)
{
return HttpNotFound();
}
Child child = _context.Child.Single(m => m.ChildId == id);
if (child == null)
{
return HttpNotFound();
}
ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent", child.ParentId);
return View(child);
}
// POST: Children/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Edit(Child child)
{
if (ModelState.IsValid)
{
_context.Update(child);
_context.SaveChanges();
return RedirectToAction("Index");
}
ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent", child.ParentId);
return View(child);
}
// GET: Children/Delete/5
[ActionName("Delete")]
public IActionResult Delete(int? id)
{
if (id == null)
{
return HttpNotFound();
}
Child child = _context.Child.Single(m => m.ChildId == id);
if (child == null)
{
return HttpNotFound();
}
return View(child);
}
// POST: Children/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public IActionResult DeleteConfirmed(int id)
{
Child child = _context.Child.Single(m => m.ChildId == id);
_context.Child.Remove(child);
_context.SaveChanges();
return RedirectToAction("Index");
}
}
}
Child Create.cshtml
@model ListBox.Web.Models.Child
@{
ViewData["Title"] = "Create";
}
<h2>Create</h2>
<form asp-action="Create">
<div class="form-horizontal">
<h4>Child</h4>
<hr />
<div asp-validation-summary="ValidationSummary.ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="ParentId" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="ParentId" class ="form-control"></select>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
</form>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
}
更改ChildrenController
中的Create()
方法,更改
public IActionResult Create()
{
ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent");
return View();
}
到
public IActionResult Create()
{
ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Name");
return View();
}
在Create.cshtml
中,更改
<select asp-for="ParentId" class="form-control"></select>
到
@Html.DropDownList("ParentId", null, htmlAttributes: new { @class = "form-control" })
生成的代码不正确,这是一个错误https://github.com/aspnet/Scaffolding/issues/149
使用 "tag helpers" 的一个解决方案是:
控制器
...
ViewData["Parents"] = new SelectList(_context.Set<Parent>(), "ParentId", "Name", child.ParentId);
...
查看
@{
var parents = (IEnumerable<SelectListItem>)ViewData["Parents"];
}
...
<select asp-for="ParentId" asp-items="parents" class ="form-control">
<option disabled selected>--- SELECT ---</option>
</select>
...
以下是当只有一种类型的对象嵌套在另一个相同类型的对象中时的操作方法。
对象:
public class Fleet
{
public int Id { get; set; }
public Fleet ParentFleet { get; set; }
public int? ParentFleetId { get; set; }
public string Name { get; set; }
[InverseProperty("ParentFleet")]
public virtual List<Fleet> Children { get; set; }
public List<UserFleet> UserFleets { get; set; }
}
控制器:
ViewData["ParentFleetId"] = new SelectList(_context.Set<Fleet>(), "Id", "Name");
return View();
查看:
<form asp-action="Create">
<div class="form-horizontal">
<h4>Fleet</h4>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="ParentFleet" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="ParentFleetId" asp-items="ViewBag.ParentFleetId" class="form-control">
<option value=""></option>
</select>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
</form>