没有 'IEnumerable<SelectListItem>' 类型的 ViewData 项具有键 'Practice' - MVC5
There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'Practice' - MVC5
I am very new to MVC and have just added a cascading drop down to my create page so when a Practice is selected the Optician drop down is populated with the names of opticians that work at that practice.
型号:
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>
级联下拉菜单正常工作,但是当我单击按钮创建约会时抛出以下异常:
异常:
An exception of type 'System.InvalidOperationException' occurred in System.Web.Mvc.dll but was not handled in user code
Additional information: There is no ViewData item of type 'IEnumerable' that has the key 'Practice'.
如有任何帮助,我们将不胜感激。
谢谢
您的模型已经包含一个属性 实践集合
public IEnumerable<SelectListItem> PracticeList { get; set; }
虽然它不应该包含
public virtual Practice Practice { get; set; }
在 GET 方法中,您为练习创建了一个新的 SelectList
,但不是将其分配给模型 属性,而是使用 [=24= 将其添加到 ViewData
]
ViewData["Practice"] = practices;
然后在视图中使用
@Html.DropDownList("Practice", ViewData["Practice"] as SelectList, ..)
它甚至没有绑定到您模型中的 属性,并且永远不会 post 返回任何东西。然后,当您 return 视图中的 POST 方法(因为您的模式将始终无效)时,您不会为 ViewData["Practice"]
赋值,因此它为空,因此出现错误。
相反,在您的 ConfigureCreateModel()
方法中,填充 PracticeList
属性(就像您对 PatientList
所做的那样)并删除 ViewData
的使用,并在视图中使用
@Html.DropDownListFor(model => model.PracticeId, Model.PracticeList, ...)
因此您与模型的绑定非常紧密,当您提交表单时,PracticeId
的值将是所选实践的值。
旁注:您需要将脚本更改为 $("#PracticeId").change(function () { ...
I am very new to MVC and have just added a cascading drop down to my create page so when a Practice is selected the Optician drop down is populated with the names of opticians that work at that practice.
型号:
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>
级联下拉菜单正常工作,但是当我单击按钮创建约会时抛出以下异常:
异常:
An exception of type 'System.InvalidOperationException' occurred in System.Web.Mvc.dll but was not handled in user code
Additional information: There is no ViewData item of type 'IEnumerable' that has the key 'Practice'.
如有任何帮助,我们将不胜感激。 谢谢
您的模型已经包含一个属性 实践集合
public IEnumerable<SelectListItem> PracticeList { get; set; }
虽然它不应该包含
public virtual Practice Practice { get; set; }
在 GET 方法中,您为练习创建了一个新的 SelectList
,但不是将其分配给模型 属性,而是使用 [=24= 将其添加到 ViewData
]
ViewData["Practice"] = practices;
然后在视图中使用
@Html.DropDownList("Practice", ViewData["Practice"] as SelectList, ..)
它甚至没有绑定到您模型中的 属性,并且永远不会 post 返回任何东西。然后,当您 return 视图中的 POST 方法(因为您的模式将始终无效)时,您不会为 ViewData["Practice"]
赋值,因此它为空,因此出现错误。
相反,在您的 ConfigureCreateModel()
方法中,填充 PracticeList
属性(就像您对 PatientList
所做的那样)并删除 ViewData
的使用,并在视图中使用
@Html.DropDownListFor(model => model.PracticeId, Model.PracticeList, ...)
因此您与模型的绑定非常紧密,当您提交表单时,PracticeId
的值将是所选实践的值。
旁注:您需要将脚本更改为 $("#PracticeId").change(function () { ...