无效的操作异常MVC C#

时间:2015-08-23 18:44:31

标签: c# asp.net-mvc database visual-studio-2013 foreign-keys

我是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;

非常感谢任何帮助

1 个答案:

答案 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插件也可以改善用户体验。