本文介绍了无效操作异常MVC C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很新的C#和MVC。我试图创建一个Web应用程序来为您预订的配镜师的做法。我已经用code-一是实体框架我的数据库。在创建预订页面我有一个下拉的地方可以选择配镜。当我创建使用CRUD的创建页面,下拉显示的用户ID,但我想改变这种状况到应用程序的用户(配镜)名字和姓氏的CONCAT(全名)。

I am very new to c# and MVC. I am trying to create a web application to make bookings for an Opticians practice. I have created my database using Code-First Entity Framework. On the create booking page I have a drop down where an Optician can be selected. When I created the create page using CRUD, the drop down showed the UserId, however I am trying to change that to a concat(FullName) of the Application Users(Optician) FirstName and LastName.

预订模型:

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>

我收到以下异常:

I am getting the following exception:

'System.InvalidOperationException'类型的异常出现在System.Web.Mvc.dll程序,但在用户code没有处理

更多信息:有型'的IEnumerable具有关键的无ViewData的项目全名

Additional information: There is no ViewData item of type 'IEnumerable' that has the key 'FullName'

任何帮助将大大AP preciated

Any help would be greatly appreciated

推荐答案

您得到这个错误的原因是因为财产全名是一个字符串,而不是的IEnumerable&LT; T&GT; ,并在您使用视图

The reason you get that error is because property FullName is a string, not IEnumerable<T> and in the view you use

 @Html.DropDownList("FullName", null, ...)

如果您提供作为第二个参数则第一个参数必须是的IEnumerable&LT; T&GT; ,其中 T 是值类型或 SelectListItem

If you provide null as the second parameter then the first parameter must be IEnumerable<T> where T is a value type or SelectListItem.

在任何情况下,全名是一个只读属性(没有一个二传手),所以它永远不会绑定到你的财产,无论如何,何况你从绑定排除属性通过你使用可怕的 [绑定(包括=...)] 属性(如果你发现自己使用它,然后使用视图模型代替)。

In any case FullName is a readonly property (does not have a setter) so it would never bind to your property anyway, not to mention you exclude the property from binding by you awful use of the [Bind(include = "...")] attribute (if you ever find yourself using it, then use a view model instead).

目前还不清楚它实际上你希望做的,因为你的的SelectList 构造函数是没有意义的。 新的SelectList(db.Opticans,OpticianId,用户ID); 意味着你生成&LT;选项&GT; 元素与属性的值等于 OpticianId 属性的值和文本等于用户ID 属性的值。但你甚至不使用它,无论如何视图。

Its unclear what your actually wanting to do since your SelectList constructors don't make sense. new SelectList(db.Opticans, "OpticianId", "UserId"); means you generating <option> elements with a value attribute equal to the value of the OpticianId property, and a text equal to the value of the UserId property. But then you don't even use it in the view anyway.

通过创建一个视图模型重新presenting要在视图中显示哪些启动

Start by creating a view model representing what you want to display in the view

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
}

和视图

@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>

终于在POST方法

and finally in the post method

[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.
}

旁注:您查看模型可以包括日期时间为MinDate 财产(包括在视图中隐藏的输入),然后申请一个万无一失的 [ GREATERTHAN] 或相似属性的日期属性让你得到客户端和服务器端验证开箱。一个jQuery插件,日期选择器限制,可以选择也将改善用户体验的日期。

Side note: You view model could include a DateTime MinDate property (include as a hidden input in the view), then apply a foolproof [GreaterThan] or similar attribute to your Date property so you get both client and server side validation out of the box. A jquery datepicker plugin that limits the dates that can be selected would also improve user experience.

这篇关于无效操作异常MVC C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 22:31