'Display FullName on DropdownListFor but submit Id - ASP.NET MVC C#
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 class="form-floating mb-3">
@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.
Solution 1:[1]
I found a solution:
- First I created a second ViewModel with a property
IdforTeacher.IdandFullNameforPerson.FirstName + " " + Person.Surname:
public class TeacherViewModel
{
public int Id { get; set; }
public string FullName { get ; set; }
}
- Then I removed the unnecessary
IEnumerable<Person> Peoplefrom my ExamViewModel and added anIEnumerable<>forTeachersof TypeTeacherViewModel:
public class ExamViewModel
{
public Exam Exam { get; set; }
public IEnumerable<TeacherViewModel> Teachers { get; set; }
}
- 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);
}
- I added a
Save()method to the controller:
public ActionResult Save(Exams exam)
{
_context.Exams.Add(exam);
_context.SaveChanges();
return RedirectToAction("Create", "Exams");
}
- Added the submit button to the View and changed the action name beside
Html.BeginForm(toSaveas it will handle saving the variables from the form.
@using (Html.BeginForm("Save", "Exams"))
{
<div class="form-floating mb-3">
@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" class="btn btn-primary">Submit</button>
}
Solution 2:[2]
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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | ismailKH |
