简体   繁体   中英

How to pass data from multiple models to a view?

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

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)
{
   (...)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM