级联下拉 - 无效值

时间:2015-09-06 16:26:23

标签: jquery ajax asp.net-mvc database cascadingdropdown

我是MVC的新手,并且很难从数据库创建级联下拉列表。选择练习后,在该练习中工作的眼镜商会填充,但不会保存到dataView Model:

public class BookingViewModel
{
    [Display (Name = "Select Patient")]
    public Guid PatientId { get; set; }
    public IEnumerable<SelectListItem> PatientList { get; set; }

    [Display(Name = "Select Practice")]
    public Guid PracticeId { get; set; }
    public IEnumerable<SelectListItem> PracticeList { get; set; }

    [Display(Name = "Select Optician")]
    public Guid OpticianId { get; set; }
    public IEnumerable<SelectListItem> OpticiansList { get; set; }

    [Display(Name = "Select Date")]
    [DataType(DataType.Date)]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
    public DateTime Date { get; set; }

    [Display(Name = "Select Time")]
    public Guid TimeId { get; set; }
    public IEnumerable<SelectListItem> TimeList { get; set; }  
}

}

My Bookings Controller:

  public ActionResult Create()
    {
        // Creates a new booking
        BookingViewModel bookingViewModel = new BookingViewModel();
        // Initilises Select List
        ConfigureCreateViewModel(bookingViewModel);

        return View(bookingViewModel);

    }

    // Initilises Select List 
    public void ConfigureCreateViewModel(BookingViewModel bookingViewModel)
    {
        // Displays Opticians Name 
        bookingViewModel.OpticiansList = db.Opticians.Select(o => new SelectListItem()
        {
            Value = o.OpticianId.ToString(),
            Text = o.User.FirstName
        });

        // Displays Patients name 
        bookingViewModel.PatientList = db.Patients.Select(p => new SelectListItem()
        {
            Value = p.PatientId.ToString(),
            Text = p.User.FirstName
        });

        // Displays Practice Name
        bookingViewModel.PracticeList = db.Practices.Select(p => new SelectListItem()
        {
            Value = p.PracticeId.ToString(),
            Text = p.PracticeName
        });

        // Displays Appointment Times 
        bookingViewModel.TimeList = db.Times.Select(t => new SelectListItem()
        {
            Value = t.TimeId.ToString(),
            Text = t.AppointmentTime
        });


    }


    // Allows Admin to create booking for patient 
    // POST: Bookings1/Create
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(BookingViewModel bookingViewModel)
    {
        // to ensure date is in the future
        if (ModelState.IsValidField("Date") && DateTime.Now > bookingViewModel.Date)
        {
            ModelState.AddModelError("Date", "Please enter a date in the future");
        }



        // if model state is not valid
        if (!ModelState.IsValid)
        {
            // Initilises Select lists
            ConfigureCreateViewModel(bookingViewModel);
            return View(bookingViewModel); // returns user to booking page


        }
        else // if model state is Valid
        {
            Booking booking = new Booking();
            // Sets isAvail to false
            booking.isAvail = false;
            booking.PracticeId = bookingViewModel.PracticeId;
            booking.OpticianId = bookingViewModel.OpticianId;
            booking.PatientId = bookingViewModel.PatientId;
            booking.Date = bookingViewModel.Date;
            booking.TimeId = bookingViewModel.TimeId;

            // 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");
        }
    }

 // Json for cascading drop down, to allow the user to select an optician from the selected practice.
    [HttpPost]
    public JsonResult Opticians(Guid Id)
    {
        var opticianList = db.Opticians.Where(a => a.PracticeId == Id).Select(a => a.User.FirstName).ToList();

        return Json(opticianList);
    }

我的观点:

<script>
$(document).ready(function () {
    $("#OpticianId").prop("disabled", true);
    $("#PracticeId").change(function () {
        $.ajax({
            url : "@Url.Action("Opticians","Bookings")",
            type : "POST",
            data : {Id : $(this).val() }
        }).done(function (opticianList) {
            $("#OpticianId").empty();
            for (var i = 0; i < opticianList.length; i++) {
                $("#OpticianId").append("<option>" + opticianList[i] + "</option>");
            }
            $("#OpticianId").prop("disabled", false);
        });
    });
});

 <div class="form-group">
        @Html.Label("Select Optician :", new { @class = "col-md-2 control-label" })
        <div class="col-md-10">

            @Html.DropDownListFor(model => model.OpticianId, Model.OpticiansList, "-Please Select-", new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.OpticianId, "", new { @class = "text-danger" })
        </div>
    </div>

级联下拉工作正常,但当我尝试将其保存到数据库时,我收到验证错误 -

  

价值&#39;名称&#39;对选择配镜师无效

非常感谢任何帮助。感谢

1 个答案:

答案 0 :(得分:1)

由于您的Opticians(Guid Id)方法仅返回User.FirstName表中的Opticians属性,因此OpticianId下拉列表的选定值会回发所选FirstName 1}}不能绑定到Guid属性的值。您生成的HTML是

<option>Some Name</option>

但它必须是

<option value="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">Some Name</option>

更改方法以返回ID和名称属性

[HttpPost]
public JsonResult Opticians(Guid Id)
{
    var opticianList = db.Opticians.Where(a => a.PracticeId == Id).Select(a => new
    {
      Value = a.OpticianId,
      Text = a.User.FirstName
    }).ToList();
    return Json(opticianList);
}

然后将脚本更改为

var opticians = $("#OpticianId"); // cache elements you repeatedly refer to
opticians.prop("disabled", true);
$("#PracticeId").change(function () {
    $.ajax({
        url : "@Url.Action("Opticians","Bookings")",
        type : "POST",
        data : {Id : $(this).val() }
    }).done(function (opticianList) {
        opticians.empty();
        $.each(opticianList, function(index, item) {
            opticians.append($('<option></option>').val(item.Value).text(item.Text));
        });
        opticians.prop("disabled", false);
    });
});