我是c#和MVC的新手。我正在尝试创建一个Web应用程序来预订眼镜师的练习。我使用Code-First Entity Framework创建了我的数据库。在创建预订页面上,我有一个可以选择配镜师的下拉菜单。当我使用CRUD创建创建页面时,下拉列表显示UserId,但我试图将其更改为应用程序用户(配镜师)FirstName和LastName的concat(FullName)。
预订模式:
public class Booking
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid BookingId { get; set; }
[ForeignKey("Patient")]
public Guid PatientId { get; set; }
public virtual Patient Patient { get; set; }
[ForeignKey("Practice")]
public Guid PracticeId { get; set; }
public virtual Practice Practice { get; set; }
[ForeignKey("Optician")]
public Guid OpticianId { get; set; }
public virtual Optician Optician { 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 bool isAvail { get; set; }
}
身份模型:
public class ApplicationUser : IdentityUser
{
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
public string LastName { get; set; }
public string FullName
{
get
{
return this.FirstName + " " + this.LastName;
}
}
配镜:
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid OpticianId { get; set; }
[ForeignKey("User")]
public string UserId { get; set; }
public virtual ApplicationUser User { get; set; }
[ForeignKey("Practice")]
public Guid PracticeId { get; set; }
public virtual Practice Practice { get; set; }
public virtual ICollection<Booking> Bookings { get; set; }
public virtual ICollection<Appointment> Appointments { get; set; }
}
预订管理员:
// GET: Bookings/Create
public ActionResult Create()
{
ViewBag.OpticianId = new SelectList(db.Opticans, "OpticianId", "UserId");
ViewBag.PatientId = new SelectList(db.Patients, "PatientId", "HCN");
ViewBag.PracticeId = new SelectList(db.Practices, "PracticeId", "PracticeName");
ViewBag.TimeId = new SelectList(db.Times, "TimeId", "AppointmentTime");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "BookingId,PatientId,PracticeId,OpticianId,Date,TimeId,isAvail")] 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;
if (ModelState.IsValid)
{
booking.BookingId = Guid.NewGuid();
db.Bookings.Add(booking);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.OpticianId = new SelectList(db.Opticans, "OpticianId", "FullName", booking.Optician.User.FullName);
ViewBag.PatientId = new SelectList(db.Patients, "PatientId", "HCN", booking.PatientId);
ViewBag.PracticeId = new SelectList(db.Practices, "PracticeId", "PracticeName", booking.PracticeId);
ViewBag.TimeId = new SelectList(db.Times, "TimeId", "AppointmentTime", booking.TimeId);
return View(booking);
}
创建视图:
<div class="form-group">
@Html.LabelFor(model => model.Optician.User.FullName, "FullName", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("FullName", null, htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Optician.User.FullName, "", new { @class = "text-danger" })
</div>
</div>
我收到以下异常:
类型&#39; System.InvalidOperationException&#39;的例外情况发生在System.Web.Mvc.dll中但未在用户代码中处理
附加信息:没有类型&#39; IEnumerable&#39;的ViewData项目。具有密钥&#39; FullName&#39;
非常感谢任何帮助
答案 0 :(得分:1)
您收到该错误的原因是因为属性FullName
是一个字符串,而不是IEnumerable<T>
,并且在您使用的视图中
@Html.DropDownList("FullName", null, ...)
如果您提供null
作为第二个参数,则第一个参数必须为IEnumerable<T>
,其中T
是值类型或SelectListItem
。
在任何情况下FullName
都是一个readonly属性(没有setter)所以它永远不会绑定到你的属性,更不用说你通过使用{{1}来排除属性绑定属性(如果你发现自己使用它,那么请使用视图模型)。
由于你的[Bind(include = "...")]
施工人员没有意义,因此不清楚你真正想要做什么。 SelectList
表示生成new SelectList(db.Opticans, "OpticianId", "UserId");
个元素,其value属性等于<option>
属性的值,文本等于OpticianId
属性的值。但是,无论如何你甚至都不在视图中使用它。
首先创建一个代表您要在视图中显示内容的视图模型
UserId
然后在控制器中
public class BookingVM
{
[Display(Name = "Optician")]
[Required(ErrorMessage = "Please select an optician")]
public Guid OpticianId { get; set; } // recommend you use int , not Guid
public IEnumerable<SelectListItem> OpticianList { get; set; }
.... // other properties to edit in the view
}
并在视图中
public ActionResult Create()
{
BookingVM model = new BookingVM();
ConfigureCreateModel(BookingVM model);
return View(model);
}
// common code for initializing select lists etc
public void ConfigureCreateModel(BookingVM model)
{
model.OpticianList = db.Opticans.Select(o => new SelectListItem()
{
Value = o.OpticianId,
Text = o.User.FullName
}
.... // other select lists
}
最后是post方法
@model BookingVM
....
<div class="form-group">
@Html.LabelFor(m => m.OpticianId, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(m => m.OpticianId, Model.OpticianList, "-Please select-", new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.OpticianId, new { @class = "text-danger" })
</div>
</div>
附注:您查看的模型可能包含[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(BookingVM model)
{
if (!ModelState.IsValid)
{
ConfigureCreateModel(model);
return View(model);
}
// map you view model properties to a new instance of your data model
// save the data model and redirect.
}
属性(在视图中包含为隐藏的输入),然后将一个万无一失的DateTime MinDate
或类似属性应用于您的[GreaterThan]
属性,以便您可以获得开箱即用的客户端和服务器端验证。限制可以选择的日期的jquery datepicker插件也可以改善用户体验。