繁体   English   中英

没有类型为“ IEnumerable”的ViewData项 <SelectListItem> 具有关键“实践”的标签-MVC5

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM