MVC 如何枚举第二个模型的数据
MVC How to Enumerate through a Second Model's Data
在“创建”视图中,我试图枚举一些 secondary/external 模型数据。相反,页面 returns 出现 NullReferenceError,我无法弄清楚为什么模型为空。如果我在为空的枚举字段上过滤 IsNull,页面将加载。
下面是Controller中的Create函数:
public IActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("SOFT_ID,SOFT_NAME,DEPT_ID,IT_CONTACT,SOFT_EXP_DATE,SOFT_SUP_PERIOD,SOFT_OUT_OF_SERVICE,VEND_ID,SUPP_ID,SOFT_IS_RENEWED")] Software software)
{
if (ModelState.IsValid)
{
_context.Add(software);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View();
}
接下来是模特。下面是 Software 模型,这是主要模型,Department 模型是次要模型。我想从其他两个模型加载数据,它们的设置与部门模型完全一样。
软件型号:
public class Software
{
[Key]
public int SOFT_ID { get; set; }
[Required]
[StringLength(50, ErrorMessage = "Software Name cannont be longer than 50 characters.")]
[Display(Name = "Software Name")]
public string SOFT_NAME { get; set; }
[Required]
public virtual Department DEPT_ID { get; set; }
[Required]
[Display(Name = "IT Contact")]
public string IT_CONTACT { get; set; }
[Required]
[Display(Name = "Expiration Date")]
[DataType(DataType.Date)]
public DateTime SOFT_EXP_DATE { get; set; }
[Required]
[Range(1,5)]
[Display(Name = "Support Period")]
public int SOFT_SUP_PERIOD { get; set; }
[Display(Name = "No Longer Used")]
public bool SOFT_OUT_OF_SERVICE { get; set; }
[Required]
public virtual Vendor VEND_ID { get; set; }
[Required]
public virtual Supplier SUPP_ID { get; set; }
[Display(Name = "Renewed?")]
public bool SOFT_IS_RENEWED { get; set; }
public IEnumerable<Department> Departments { get; set; }
public IEnumerable<Supplier> Suppliers { get; set; }
public IEnumerable<Vendor> Vendors { get; set; }
}
部门模型:
public class Department
{
[Key]
public int DEPT_ID { get; set; }
[Required]
[Display(Name = "Department Name")]
public string DEPT_NAME { get; set; }
[Required]
[Display(Name = "Department Contact Name")]
public string DEPT_CONTACT { get; set; }
[Required]
[Display(Name = "Email")]
public string DEPT_EMAIL { get; set; }
[Required]
[Display(Name = "Phone")]
public string DEPT_PHONE { get; set; }
}
最后是视图。抛出 NullReferenceError 的部分是部门、供应商和供应商的 @foreach 循环。这些应该是填充下拉菜单。
@model SoftwareManager_SSO.Models.Software
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Software</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="SOFT_NAME" class="control-label"></label>
<input asp-for="SOFT_NAME" class="form-control" />
<span asp-validation-for="SOFT_NAME" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="DEPT_ID.DEPT_NAME" class="control-label"></label>
<select class="form-control">
<option value="" disabled selected>Select A Dept</option>
@foreach (var item in Model.Departments)
{
<option value="@item.DEPT_ID">@item.DEPT_NAME</option>
}
</select>
<span asp-validation-for="DEPT_ID.DEPT_NAME"></span>
</div>
<div hidden="hidden" class="form-group">
<label asp-for="DEPT_ID" class="control-label"></label>
<input asp-for="DEPT_ID" class="form-control" disabled="disabled" />
<span asp-validation-for="DEPT_ID" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="DEPT_ID.DEPT_CONTACT" class="control-label"></label>
<input id="dept_contact" asp-for="DEPT_ID.DEPT_CONTACT" disabled="disabled" class="form-control" />
<span asp-validation-for="DEPT_ID.DEPT_CONTACT" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="IT_CONTACT" class="control-label"></label>
<select class="form-control">
<option value="" selected>Select IT Person</option>
<option value="uciltas@tohowater.com">Umit Ciltas</option>
<option value="sslaven@tohowater.com">Stephen Slaven</option>
<option value="imoreno@tohowater.com">Ismael Moreno</option>
<option value="dkearney@tohowater.com">David Kearney</option>
</select>
<span asp-validation-for="IT_CONTACT" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="SOFT_EXP_DATE" class="control-label"></label>
<input asp-for="SOFT_EXP_DATE" class="form-control" />
<span asp-validation-for="SOFT_EXP_DATE" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="SOFT_SUP_PERIOD" class="control-label"></label>
<select class="form-control">
<option value="" selected>Select A Support Period</option>
<option value="1">1 Year</option>
<option value="2">2 Years</option>
<option value="3">3 Years</option>
<option value="4">4 Years</option>
<option value="5">5 Years</option>
</select>
<span asp-validation-for="SOFT_SUP_PERIOD" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="VEND_ID.VEND_NAME" class="control-label"></label>
<select class="form-control">
<option value="" disabled selected>Select a Vendor</option>
@foreach (var item in Model.Vendors)
{
<option value="@item.VEND_ID">@item.VEND_NAME</option>
}
</select>
<span asp-validation-for="VEND_ID.VEND_NAME"></span>
</div>
<div class="form-group">
<label asp-for="SUPP_ID.SUPP_NAME" class="control-label"></label>
<select class="form-control">
<option value="" disabled selected>Select a Vendor</option>
@foreach (var item in Model.Suppliers)
{
<option value="@item.SUPP_ID">@item.SUPP_NAME</option>
}
</select>
<span asp-validation-for="SUPP_ID.SUPP_NAME"></span>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="SOFT_IS_RENEWED" /> @Html.DisplayNameFor(model => model.SOFT_IS_RENEWED)
</label>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="SOFT_OUT_OF_SERVICE" /> @Html.DisplayNameFor(model => model.SOFT_OUT_OF_SERVICE)
</label>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
老实说,我很茫然,想不通。我已经阅读了该站点上的许多其他帖子,但我无法弄清楚我的代码与我看到的类似代码之间有什么不同。我将继续搜索所有帖子,但如有任何帮助,我们将不胜感激。
您需要将有关这些部门的信息传递到视图中。这通常是通过创建视图模型并将其传递给视图来完成的。
在您的代码中,您的视图需要一个“软件”模型,因此您可以创建一个(并确保填充“部门”)并将其传递到您的视图中。
获得模型后,您可以使用 Html 助手生成下拉菜单,而不是使用循环手动构建它。
例如:
@Html.DropDownListFor(model => model.departments )
或者也许
@Html.DropDownListFor(model => model.departments as selectlist)
抱歉,如果某些语法不太正确,在我的手机上无法很好地检查。但这应该会给你正确的想法。
编辑
您需要在控制器中构建视图模型并将其传递给视图。
var viewModel = new Software();
viewModel.Departments = new List<Department>() {
new Department() { DEPT_NAME = "Some department name"}
};
return View(viewModel);
或者如果从数据库动态拉取(例如通过entity framework):
var viewModel = new Software();
viewModel.Departments = _db.Departments.ToList()
return View(viewModel);
在“创建”视图中,我试图枚举一些 secondary/external 模型数据。相反,页面 returns 出现 NullReferenceError,我无法弄清楚为什么模型为空。如果我在为空的枚举字段上过滤 IsNull,页面将加载。
下面是Controller中的Create函数:
public IActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("SOFT_ID,SOFT_NAME,DEPT_ID,IT_CONTACT,SOFT_EXP_DATE,SOFT_SUP_PERIOD,SOFT_OUT_OF_SERVICE,VEND_ID,SUPP_ID,SOFT_IS_RENEWED")] Software software)
{
if (ModelState.IsValid)
{
_context.Add(software);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View();
}
接下来是模特。下面是 Software 模型,这是主要模型,Department 模型是次要模型。我想从其他两个模型加载数据,它们的设置与部门模型完全一样。
软件型号:
public class Software
{
[Key]
public int SOFT_ID { get; set; }
[Required]
[StringLength(50, ErrorMessage = "Software Name cannont be longer than 50 characters.")]
[Display(Name = "Software Name")]
public string SOFT_NAME { get; set; }
[Required]
public virtual Department DEPT_ID { get; set; }
[Required]
[Display(Name = "IT Contact")]
public string IT_CONTACT { get; set; }
[Required]
[Display(Name = "Expiration Date")]
[DataType(DataType.Date)]
public DateTime SOFT_EXP_DATE { get; set; }
[Required]
[Range(1,5)]
[Display(Name = "Support Period")]
public int SOFT_SUP_PERIOD { get; set; }
[Display(Name = "No Longer Used")]
public bool SOFT_OUT_OF_SERVICE { get; set; }
[Required]
public virtual Vendor VEND_ID { get; set; }
[Required]
public virtual Supplier SUPP_ID { get; set; }
[Display(Name = "Renewed?")]
public bool SOFT_IS_RENEWED { get; set; }
public IEnumerable<Department> Departments { get; set; }
public IEnumerable<Supplier> Suppliers { get; set; }
public IEnumerable<Vendor> Vendors { get; set; }
}
部门模型:
public class Department
{
[Key]
public int DEPT_ID { get; set; }
[Required]
[Display(Name = "Department Name")]
public string DEPT_NAME { get; set; }
[Required]
[Display(Name = "Department Contact Name")]
public string DEPT_CONTACT { get; set; }
[Required]
[Display(Name = "Email")]
public string DEPT_EMAIL { get; set; }
[Required]
[Display(Name = "Phone")]
public string DEPT_PHONE { get; set; }
}
最后是视图。抛出 NullReferenceError 的部分是部门、供应商和供应商的 @foreach 循环。这些应该是填充下拉菜单。
@model SoftwareManager_SSO.Models.Software
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Software</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="SOFT_NAME" class="control-label"></label>
<input asp-for="SOFT_NAME" class="form-control" />
<span asp-validation-for="SOFT_NAME" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="DEPT_ID.DEPT_NAME" class="control-label"></label>
<select class="form-control">
<option value="" disabled selected>Select A Dept</option>
@foreach (var item in Model.Departments)
{
<option value="@item.DEPT_ID">@item.DEPT_NAME</option>
}
</select>
<span asp-validation-for="DEPT_ID.DEPT_NAME"></span>
</div>
<div hidden="hidden" class="form-group">
<label asp-for="DEPT_ID" class="control-label"></label>
<input asp-for="DEPT_ID" class="form-control" disabled="disabled" />
<span asp-validation-for="DEPT_ID" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="DEPT_ID.DEPT_CONTACT" class="control-label"></label>
<input id="dept_contact" asp-for="DEPT_ID.DEPT_CONTACT" disabled="disabled" class="form-control" />
<span asp-validation-for="DEPT_ID.DEPT_CONTACT" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="IT_CONTACT" class="control-label"></label>
<select class="form-control">
<option value="" selected>Select IT Person</option>
<option value="uciltas@tohowater.com">Umit Ciltas</option>
<option value="sslaven@tohowater.com">Stephen Slaven</option>
<option value="imoreno@tohowater.com">Ismael Moreno</option>
<option value="dkearney@tohowater.com">David Kearney</option>
</select>
<span asp-validation-for="IT_CONTACT" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="SOFT_EXP_DATE" class="control-label"></label>
<input asp-for="SOFT_EXP_DATE" class="form-control" />
<span asp-validation-for="SOFT_EXP_DATE" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="SOFT_SUP_PERIOD" class="control-label"></label>
<select class="form-control">
<option value="" selected>Select A Support Period</option>
<option value="1">1 Year</option>
<option value="2">2 Years</option>
<option value="3">3 Years</option>
<option value="4">4 Years</option>
<option value="5">5 Years</option>
</select>
<span asp-validation-for="SOFT_SUP_PERIOD" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="VEND_ID.VEND_NAME" class="control-label"></label>
<select class="form-control">
<option value="" disabled selected>Select a Vendor</option>
@foreach (var item in Model.Vendors)
{
<option value="@item.VEND_ID">@item.VEND_NAME</option>
}
</select>
<span asp-validation-for="VEND_ID.VEND_NAME"></span>
</div>
<div class="form-group">
<label asp-for="SUPP_ID.SUPP_NAME" class="control-label"></label>
<select class="form-control">
<option value="" disabled selected>Select a Vendor</option>
@foreach (var item in Model.Suppliers)
{
<option value="@item.SUPP_ID">@item.SUPP_NAME</option>
}
</select>
<span asp-validation-for="SUPP_ID.SUPP_NAME"></span>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="SOFT_IS_RENEWED" /> @Html.DisplayNameFor(model => model.SOFT_IS_RENEWED)
</label>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="SOFT_OUT_OF_SERVICE" /> @Html.DisplayNameFor(model => model.SOFT_OUT_OF_SERVICE)
</label>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
老实说,我很茫然,想不通。我已经阅读了该站点上的许多其他帖子,但我无法弄清楚我的代码与我看到的类似代码之间有什么不同。我将继续搜索所有帖子,但如有任何帮助,我们将不胜感激。
您需要将有关这些部门的信息传递到视图中。这通常是通过创建视图模型并将其传递给视图来完成的。
在您的代码中,您的视图需要一个“软件”模型,因此您可以创建一个(并确保填充“部门”)并将其传递到您的视图中。
获得模型后,您可以使用 Html 助手生成下拉菜单,而不是使用循环手动构建它。
例如:
@Html.DropDownListFor(model => model.departments )
或者也许
@Html.DropDownListFor(model => model.departments as selectlist)
抱歉,如果某些语法不太正确,在我的手机上无法很好地检查。但这应该会给你正确的想法。
编辑
您需要在控制器中构建视图模型并将其传递给视图。
var viewModel = new Software();
viewModel.Departments = new List<Department>() {
new Department() { DEPT_NAME = "Some department name"}
};
return View(viewModel);
或者如果从数据库动态拉取(例如通过entity framework):
var viewModel = new Software();
viewModel.Departments = _db.Departments.ToList()
return View(viewModel);