Reputation: 43
I have 3 models
Student
public class Student
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; } //primary key
[RegularExpression(@"^[ A-Za-z]*$", ErrorMessage = "Only Alphabet allowed")]
[Required] //Because you can't leave this field empty
public string Name { get; set; }
[RegularExpression(@"^[ A-Za-z]*$", ErrorMessage = "Only Alphabet allowed")]
[Required]
public string LastName { get; set; }
[RegularExpression(@"^(\d{1,3})/\d{4}$", ErrorMessage = "Format has to be 1-3digit number/year; example 100/2015")]
[Required]
public string BI { get; set; }
}
Subject
public class Subject
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[RegularExpression(@"^[ A-Za-z0-9]*$", ErrorMessage = "Only Alphabet and numbers allowed")]
[Required]
public string SubjectName { get; set; }
}
Exam
public class Exam
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public int StudentID { get; set; }
public int SubjectID { get; set; }
[Range(6, 10)]
public int Grade { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime EnrollmentDate { get; set; }
}
ViewModel
public class ViewModel
{
public Student Students;
public IEnumerable<Exam> Exams;
public IEnumerable<Subject> Subjects;
}
I want to pass data from StudentsController to edit.cshtml, to be able to edit SubjectName and Grade from dropdown menu. I also created ViewModel from these 3, and included ViewModel. I just don't know how to pass ViewModel from controller to a view. Any ideas?
Controller edit
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var student = await _context.Student.SingleOrDefaultAsync(m => m.ID == id);
if (student == null)
{
return NotFound();
}
return View(student);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,Name,LastName,BI,SubjectName,Grade")] ViewModel student)
{
if (id != student.Students.ID)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(student);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!StudentExists(student.Students.ID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(student);
}
Upvotes: 2
Views: 75
Reputation: 782
I think a viewmodel
should just have properties that you are going to use on that view
and not the entire model
.
But you can pass a ViewModel
like this:
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var student = await _context.Student.SingleOrDefaultAsync(m => m.ID == id);
if (student == null)
{
return NotFound();
}
ViewModel model = new ViewModel();
model.Student = student;
return View(model);
}
And then on your edit.cshtml
you need to @model namespace.ViewModel
Then on you Post
method you should also use your ViewModel
instead of a Bind
:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, ViewModel model)
{
(...)
}
Upvotes: 3