Thursday, July 27, 2017

ASP.Net MVC - Multiple Models in Single View - Part2

In last post, we have talked about different approaches to pass the multiple models in single view. We have also looked some of them like Dynamic,View Data and View Bag.

This post is the continuation of previous post. Here we will see the use of ViewModel,Tuple and ViewComponent for passing multiple model in single view . Let's first see what was our problem statement-

Problem Statement

We have two models Student and Course and we need to show the the list of Students and Courses in a single view.

Below are the model definition for Student and Course
public class Student
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }       
}

public class Course
{
    public int CourseID { get; set; }
    public string CourseName { get; set; }
}

Solutions to achieve

Here we will see ViewModel,Tuple and ViewComponent to achieve our requirement

1. View Model

ViewModel is a class which contains the properties which are represented in view or represents the data that we want to display on our view.

If we want to create a View where we want to display list of Students and Courses then we will create our View Model (StudentCourseViewModel.cs).

ViewModel Class

public class StudentCourseViewModel
{
   public List<Course> allCourses { get; set; }
   public List<Student> allStudents { get; set; }
}

Action Method

public IActionResult UsingViewModel()
{
    ViewBag.Message = "Passing Multiple Model using ViewModel";
    StudentCourseViewModel vm = new StudentCourseViewModel();
    vm.allStudents = Repository.GetStudents();
    vm.allCourses = Repository.GetCourses();
    return View(vm);
}

View Code

@using MVCCustomModelBinding.Models.ViewModels
@model StudentCourseViewModel
@{
    ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>

<h3>Student List</h3>

<div class="row">
    <div class="col-lg-6">
        <table class="table table-responsive table-bordered">
            <thead><tr><th align="center">Student ID</th><th align="center">Student Name</th></tr></thead>
            <tbody>
                @foreach (var item in Model.allStudents)
            {
                    <tr><td>@item.StudentID</td><td>@item.StudentName</td></tr>
                }
            </tbody>
        </table>
    </div>
</div>
<h3>Course List</h3>

<div class="row">
    <div class="col-lg-6">
        <table class="table table-responsive table-bordered">
            <thead><tr><th align="center">Course ID</th><th align="center">Course Name</th></tr></thead>
            <tbody>
                @foreach (var item in Model.allCourses)
            {
                    <tr><td>@item.CourseID</td><td>@item.CourseName</td></tr>
                }
            </tbody>
        </table>
    </div>
</div>

2. Tuple

A Tuple object is an immutable, fixed-size and ordered sequence object. Each object in tuple is being of a specific type.The .NET framework supports tuples up to seven elements.

Using this tuple object we can pass multiple models from the controller to the view.

Action Method

public IActionResult UsingTuple()
{
    ViewBag.Message = "Passing Multiple Model using Tuple";
    var tupleModel = new Tuple<List<Student>, List<Course>>(Repository.GetStudents(), Repository.GetCourses());
    return View(tupleModel);
}

View Code

@using MVCCustomModelBinding.Models
@model Tuple<List<Student>,List<Course>>
@{
    ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>

<h3>Student List</h3>

<div class="row">
    <div class="col-lg-6">
        <table class="table table-responsive table-bordered">
            <thead><tr><th align="center">Student ID</th><th align="center">Student Name</th></tr></thead>
            <tbody>
                @foreach (var item in Model.Item1)
            {
                    <tr><td>@item.StudentID</td><td>@item.StudentName</td></tr>
                }
            </tbody>
        </table>
    </div>
</div>
<h3>Course List</h3>

<div class="row">
    <div class="col-lg-6">
        <table class="table table-responsive table-bordered">
            <thead><tr><th align="center">Course ID</th><th align="center">Course Name</th></tr></thead>
            <tbody>
                @foreach (var item in Model.Item2)
            {
                    <tr><td>@item.CourseID</td><td>@item.CourseName</td></tr>
                }
            </tbody>
        </table>
    </div>
</div>

3. ViewComponent (ASP.NET Core MVC feature)

As part of ASP.NET MVC 6, a new feature called View Components has been introduced. View components are similar to child actions and partials views, allowing you to create reusable components with (or without) logic.

View components are made up of 2 parts: A view component class and a razor view.

To implement the view component class, inherit from the base ViewComponent and implement an Invoke or InvokeAsync method. This class can be anywhere in your project. A common convention is to place them in a ViewComponents folder.

Here we will create the two ViewComponent classes (StudentViewComponent and CourseViewComponent).These classes can be anywhere in your project. A common convention is to place them in a ViewComponents folder.

ViewComponentClass

public class StudentViewComponent : ViewComponent
{
   public IViewComponentResult Invoke()
   {
     return View("ViewStudents", Repository.GetStudents());
   }
}
public class CourseViewComponent : ViewComponent
{
  public IViewComponentResult Invoke()
  {
   return View("ViewCourses", Repository.GetCourses());
  }
}
As you can see that in both the ViewComponets(StudentViewComponent and CourseViewComponent), we are implementing the Invokemethod which are returning a views ViewStudents and ViewCourses respectively.Below are the cshtml code for ViewStudents and ViewCourses respectively.

ViewStudents.cshtml

@using MVCCustomModelBinding.Models
@model List<Student>

<h3>Student List</h3>

<div class="row">
    <div class="col-lg-6">
        <table class="table table-responsive table-bordered">
            <thead><tr><th align="center">Student ID</th><th align="center">Student Name</th></tr></thead>
            <tbody>
                @foreach (var item in Model)
            {
                    <tr><td>@item.StudentID</td><td>@item.StudentName</td></tr>
                }
            </tbody>
        </table>
    </div>
</div>

ViewCourses.cshtml

@using MVCCustomModelBinding.Models
@model List<Course>

<h3>Course List</h3>

<div class="row">
    <div class="col-lg-6">
        <table class="table table-responsive table-bordered">
            <thead><tr><th align="center">Course ID</th><th align="center">Course Name</th></tr></thead>
            <tbody>
                @foreach (var item in Model)
            {
                    <tr><td>@item.CourseID</td><td>@item.CourseName</td></tr>
                }
            </tbody>
        </table>
    </div>
</div>

Controller Action Method

public IActionResult UsingViewComponent()
{
   ViewBag.Message = "Passing Multiple Model using ViewComponent";
   return View();
}

View Code

@using MVCCustomModelBinding.Models.ViewModels
@model StudentCourseViewModel
@{
    ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>

@await Component.InvokeAsync("Student")
@await Component.InvokeAsync("Course")

Output

aspnet-mvc-multiplemodel
I hope this will be helpful  for you. Happy Coding!!

No comments:

Post a Comment

^ Scroll to Top