Home > Blockchain >  Display FullName on DropdownListFor but submit Id - ASP.NET MVC C#
Display FullName on DropdownListFor but submit Id - ASP.NET MVC C#

Time:05-11

I'm trying to build a form for information about upcoming exams. My plan is to make a dropdown list which shows a List of teachers to chose from and who will be responsible for the exam.

Here's a simplified version of my Models:

public class Person
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string Surname { get; set; }
    }
public class Teacher
    {
        public int Id { get; set; }
        public int PersonId { get; set; }
        public Person Person { get; set; }
    }
public class Exam
    {
        public int Id { get; set; }
        public string Subject { get; set; }
        public DateTime ExamDate { get; set; }
        public int TeacherId { get; set; }
        public Teacher Teacher { get; set; }
    }

My ViewModel:

public class ExamViewModel
    {
        public Exam Exam { get; set; }
        public IEnumerable<Person> People { get; set; }
        public IEnumerable<Teacher> Teachers { get; set; }
    }

And my Create action from ExamController:

public ActionResult Create()
        {
            var people = _context.People.ToList();
            var teachers = _context.Teachers.ToList();

            var viewModel = new ExamViewModel
            {
                People = people,
                Teachers = teachers,
            };

            return View(viewModel);
        }

I'd like to display People.Firstname " " People.Surname of all teachers on the dropdown mentioned above, but instead of submitting People.Id I'd like to submit Teachers.Id to Exams.TeacherId

I first tried to displaying a list of the all FirstName before trying displaying FirstName and Surname with the following razor html helper in my Create view but I already failed there as I was only able to access the properties from one single class (Teachers) to use is as dataValueField and dataTextField for new SelectList():

<h2>Plan exam</h2>
@using (Html.BeginForm("Create", "ExamController"))
{
    <div >
        @Html.DropDownListFor(m => m.Exam.TeacherId, new SelectList(Model.Teachers, "Id", "FirstName"), "-- Please select --", new { @class = "form-control", @placeholder = "Teacher" })
        @Html.LabelFor(m => m.Exam.TeacherId)
    </div>
}

I'm quite new to programming so I'd be very very grateful for any kind of help.

CodePudding user response:

in your viewModel you can only send Exams , but in the query to fetch exams you must make a join to fetch for every exam the teacherID , teacherName , teacherSubname, to Learn about that check this : here or this : here

another thing , in your model ( classes ) definition , i think you have to add a relationship between Exam and Teacher , and between Teacher an People , if you do so it will be easier to fetch only the necessary data , and you will use only one property ( exams ) in your viewModel to send data to the view, to do so check this here

CodePudding user response:

I found a solution:

  1. First I created a second ViewModel with a property Id for Teacher.Id and FullName for Person.FirstName " " Person.Surname:
public class TeacherViewModel
    {
        public int Id { get; set; }
        public string FullName { get ; set; }
    }
  1. Then I removed the unnecessary IEnumerable<Person> People from my ExamViewModel and added an IEnumerable<> for Teachers of Type TeacherViewModel:
public class ExamViewModel
    {
        public Exam Exam { get; set; }
        public IEnumerable<TeacherViewModel> Teachers { get; set; }
    }
  1. I created a join as mentionen at step 1, converted it to a list in the new TeacherViewModel:
public ActionResult Create()
        {
            var teachers = (from t in _context.Teachers
                           join p in _context.People
                           on t.PersonId equals p.Id
                           select new TeacherViewModel
                           {
                               Id = t.Id,
                               FullName = p.FirstName   " "   p.Surname,
                           }).ToList();

            var viewModel = new ExamViewModel
            {
                Teachers = teachers,
            };

            return View(viewModel);
        }
  1. I added a Save() method to the controller:
public ActionResult Save(Exams exam)
        {
            _context.Exams.Add(exam);
            _context.SaveChanges();
            
            return RedirectToAction("Create", "Exams");
        }
  1. Added the submit button to the View and changed the action name beside Html.BeginForm( to Save as it will handle saving the variables from the form.
@using (Html.BeginForm("Save", "Exams"))
{
    <div >
        @Html.DropDownListFor(m => m.Exam.TeacherId, new SelectList(Model.Teachers, "Id", "FullName"), "-- please select --", new { @class = "form-control", @placeholder = "Teacher" })
        @Html.LabelFor(m => m.Exam.TeacherId)
    </div>
    <button type="submit" >Submit</button>
}
  • Related