
[英]There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key
[英]There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'Practice' - MVC5
我是MVC的新手,并且刚刚在我的创建页面中添加了一个级联下拉菜单,因此当选择“练习”时,“眼镜师”下拉列表中会填充在该练习中工作的配镜师的姓名。
模型:
public class Booking
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid BookingId { get; set; }
[ForeignKey("Patient")]
public Guid PatientId { get; set; }
public virtual Patient Patient { get; set; }
public IEnumerable<SelectListItem> PatientList { get; set; }
[ForeignKey("Practice")]
public Guid PracticeId { get; set; }
public virtual Practice Practice { get; set; }
public IEnumerable<SelectListItem> PracticeList { get; set; }
[ForeignKey("Optician")]
public Guid OpticianId { get; set; }
public virtual Optician Optician { get; set; }
public IEnumerable<SelectListItem> OpticiansList { get; set; }
[Display(Name = "Date")]
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime Date { get; set; }
[ForeignKey("Time")]
public Guid? TimeId { get; set; }
public virtual Time Time { get; set; }
public IEnumerable<SelectListItem> TimeList { get; set; }
public bool isAvail { get; set; }
}
我的控制器:
// GET: Bookings1/Create
public ActionResult Create()
{
var practices = new SelectList(db.Practices, "PracticeId", "PracticeName");
ViewData["Practice"] = practices;
Booking booking = new Booking();
ConfigureCreateModel(booking);
return View(booking);
}
public void ConfigureCreateModel(Booking booking)
{
booking.PatientList = db.Patients.Select(p => new SelectListItem()
{
Value = p.PatientId.ToString(),
Text = p.User.FirstName
});
booking.TimeList = db.Times.Select(t => new SelectListItem()
{
Value = t.TimeId.ToString(),
Text = t.AppointmentTime
});
}
// POST: Bookings1/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Booking booking)
{
// to ensure date is in the future
if (ModelState.IsValidField("Date") && DateTime.Now > booking.Date)
{
ModelState.AddModelError("Date", "Please enter a date in the future");
}
// Sets isAvail to false
booking.isAvail = false;
//Checks if model state is not valid
if (!ModelState.IsValid)
{
ConfigureCreateModel(booking);
return View(booking); // returns user to booking page
}
else // if model state is Valid
{
// Generates a new booking Id
booking.BookingId = Guid.NewGuid();
// Adds booking to database
db.Bookings.Add(booking);
// Saves changes to Database
db.SaveChanges();
// Redirects User to Booking Index
return RedirectToAction("Index");
}
}
我的观点:
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script>
$(document).ready(function () {
$("#Optician").prop("disabled", true);
$("#Practice").change(function () {
$.ajax({
url : "@Url.Action("Opticians","Bookings")",
type : "POST",
data : {Id : $(this).val() }
}).done(function (opticianList) {
$("#Optician").empty();
for (var i = 0; i < opticianList.length; i++) {
$("#Optician").append("<option>" + opticianList[i] + "</option>");
}
$("#Optician").prop("disabled", false);
});
});
});
</script>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Booking</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.PatientId, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.PatientId, Model.PatientList, "-Please select-", new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.PatientId, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.PracticeId, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("Practice", ViewData["Practice"] as SelectList,"-Please Select-", new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.PracticeId, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.Label("Select Optician :", new { @class = "col-md-2 control-label" })
<div class="col-md-10">
<select id="Optician"></select>
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Date, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Date, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Date, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.TimeId, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.TimeId, Model.TimeList, "-Please select-", new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.TimeId, "", new { @class = "text-danger" })
</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>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
当我单击按钮创建约会时,级联下拉菜单的工作方式应该一样,将引发以下异常:
例外:
System.Web.Mvc.dll中发生类型为'System.InvalidOperationException'的异常,但未在用户代码中处理
附加信息:没有类型为“ IEnumerable”的ViewData项目具有键“ Practice”。
任何帮助将不胜感激。 谢谢
您的模型已经包含用于实践收集的属性
public IEnumerable<SelectListItem> PracticeList { get; set; }
虽然它不应该包含
public virtual Practice Practice { get; set; }
在GET方法中,为实践创建一个新的SelectList
,但没有将其分配给model属性,而是使用以下方法将其添加到ViewData
中:
ViewData["Practice"] = practices;
然后在视图中使用
@Html.DropDownList("Practice", ViewData["Practice"] as SelectList, ..)
甚至没有绑定到模型中的属性,也永远不会发回任何东西。 然后,当您在POST方法中返回视图时(因为您的模式将始终无效),则无需为ViewData["Practice"]
分配一个值,因此它为null,从而导致错误。
相反,在您的ConfigureCreateModel()
方法中,填充PracticeList
属性(就像对PatientList
所做的PatientList
)并删除对ViewData
的使用,并在视图中使用
@Html.DropDownListFor(model => model.PracticeId, Model.PracticeList, ...)
因此,您对模型具有很强的约束力,并且在提交表单时, PracticeId
的值将是所选实践的值。
旁注:您需要将脚本更改为$("#PracticeId").change(function () { ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.