Home > Enterprise >  Why is the DepartmentID value not being properly bound to the view model's property?
Why is the DepartmentID value not being properly bound to the view model's property?

Time:04-03

Not sure why but the for some reason the view model is not binding the DepartmentId when I hit the submit button, I get an error:

Value cannot be null.
Parameter name: value

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Not sure which value is being null as the code does not break, rather after hitting the submit button that is the message that is being displayed.

I'm assuming it's the departmentId that's not being properly bound to the DepartmentID property in CoursePreReqViewModel.

Exception Details: System.ArgumentNullException: Value cannot be null.
Parameter name: value

View:

@using (Html.BeginForm("Catalog", "Courses", FormMethod.Post, new { @class = "pure-form pure-form-aligned" }))
{
    @Html.AntiForgeryToken()
    <div >
        <div >
            <input id="myInput"  type="text" placeholder="Search..">
        </div>
        <div >
            @Html.LabelFor(model => model.DepartmentId, htmlAttributes: new { @class = "control-label col-md-2" })
            @Html.DropDownListFor(model => model.DepartmentId, Model.DepartmentList, "Department", new { @class = "form-control required", id = "department-list" })
            @Html.ValidationMessageFor(model => model.DepartmentId)
            
        </div>
        <div >
            <button type="submit" >Submit</button>
        </div>
    </div>
}

Controller:

[HttpPost]
public ActionResult Catalog(CoursePreReqViewModel viewModel)
{
    DepartmentRepo dRepo;
    CoursesRepo cRepo;
    MajorPreRequisitesRepo reqRepo;

    using (context)
    {
        dRepo = new DepartmentRepo(context);
        cRepo = new CoursesRepo(context);
        viewModel.PopulateDepermentSelectList(dRepo.GetAllDepartments());
        reqRepo = new MajorPreRequisitesRepo(context);
        viewModel.Courses = cRepo.GetAllCoursesAndPreReqsByDepartment(viewModel.DepartmentId);
    }

    return View(viewModel);
}

View model:

public class CoursePreReqViewModel
{
    [Required]
    [Display(Name = "")]
    public int DepartmentId { get; set; }
    public IList<Course> Courses { get; set; }
    public IList<MajorPreRequisite> CoursesAndPreReqs { get; set; }
    [Display(Name = "Department: ")]
    public IList<Department> Departments { get; set; }

    public CoursePreReqViewModel() { }

    public SelectList DepartmentList
    {
        get
        {
            return new SelectList(Departments, "Id", "Name");
        }
    }

    public void PopulateDepartmentSelectList(IList<Department> populatedDepartments)
    {
        Departments = populatedDepartments;
    }
}

CodePudding user response:

I can help you keep the code you have, and answer your question.

controller/classes:

public class Course
{
    public int CourseId { get; set; }
}
public class MajorPreRequisite
{
    public int MajorPreRequisiteId { get; set; }

}
public class Department
{
    public int Id { get; set; }
    public string Name { get; set; }
}
public class CoursePreReqViewModel
{
    //Make sure to comment this out -or- put this field in view
    //try this first with your code, before you change code eg using a dictionary
    //[Required]
    //[Display(Name = "")]
    public int DepartmentId { get; set; }
    public IList<Course> Courses { get; set; }
    public IList<MajorPreRequisite> CoursesAndPreReqs { get; set; }
    [Display(Name = "Department: ")]
    public IList<Department> Departments { get; set; }
    public CoursePreReqViewModel() { }
    public Dictionary<string, string> DepartmentList { get; set; }
    public void GetAllCoursesAndPreReqsByDepartment(IList<Course> populateCourses)
    {
        Courses = populateCourses;
    }
}
public class HomeController : Controller
{
    [HttpPost]
    public ActionResult Catalog(CoursePreReqViewModel viewModel)
    {
        //Put a breakpoint herre to see departmentid of user choice
        return View();
    }
    public ActionResult Index11()
    {
        CoursePreReqViewModel viewModel = new CoursePreReqViewModel();
        Dictionary<string, string> depts = new Dictionary<string, string>();
        depts.Add("1", "deptOne");
        depts.Add("2", "deptTwo");
        viewModel.DepartmentList = depts;

        IList<Course> courses = new List<Course>();
        courses.Add(new Course { CourseId = 1 });
        courses.Add(new Course { CourseId = 2 });
        viewModel.GetAllCoursesAndPreReqsByDepartment(courses);

        return View(viewModel);
    }

view:

@model WebApplication4what2.Controllers.CoursePreReqViewModel
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index11</title>
</head>
<body>
    @using (Html.BeginForm("Catalog", "Home", FormMethod.Post, new { @class = "pure-form pure-form-aligned" }))
    {
        <div >
            <div >
                <input id="myInput"  type="text" placeholder="Search..">
            </div>
            <div >
                @Html.LabelFor(model => model.DepartmentId, htmlAttributes: new { @class = "control-label col-md-2" })
                @Html.DropDownListFor(model => model.DepartmentId, new SelectList(Model.DepartmentList, "Key", "Value"), Model.DepartmentId)
                @Html.ValidationMessageFor(model => model.DepartmentId)
            </div>
            <div >
                <button type="submit" >Submit</button>
            </div>
        </div>
    }
</body>
</html>

CodePudding user response:

Sarthak here is another answer: this is the asp.net mvc fiddler https://dotnetfiddle.net/ARdtvr !!!Display Name needs to be a value!!!

  • Related