Search in Help for developer site.

Monday 26 December 2016

When to use Abastract Class over Interface in C#

Recommendations for Abstract Classes vs. Interfaces

An abstract class is a class that cannot be instantiated, but must be inherited from. An abstract class may be fully implemented, but is more usually partially implemented or not implemented at all, thereby encapsulating common functionality for inherited classes.

An interface, by contrast, is a totally abstract set of members. The implementation of an interface is left completely to the developer.


Some recommendations to help you to decide whether to use an interface or an abstract class

  • If you anticipate creating multiple versions of your component, create an abstract class. Abstract classes provide a simple and easy way to version your components. By updating the base class, all inheriting classes are automatically updated with the change. Interfaces, on the other hand, cannot be changed once created. If a new version of an interface is required, you must create a whole new interface.

  • If the functionality you are creating will be useful across a wide range of disparate objects, use an interface. Abstract classes should be used primarily for objects that are closely related, whereas interfaces are best suited for providing common functionality to unrelated classes.

  • If you are designing small, concise bits of functionality, use interfaces. If you are designing large functional units, use an abstract class.

  • If you want to provide common, implemented functionality among all implementations of your component, use an abstract class. Abstract classes allow you to partially implement your class, whereas interfaces contain no implementation for any members. We can ensure a certain amount of identical functionality with an abstract class, but cannot with an interface.
Source : msdn

Monday 5 December 2016

Best Practice for Showing Data of Multiple Models to a View

Introduction

In MVC we cannot pass multiple models from a controller to the single view. This article provides a workaround for multiple models in a single view.

Problem Statement

Suppose we have two models, Teacher and Student, and we need to display a list of teachers and students within a single view. How can we do this?

The following are the model definitions for the teacher and student classes.

public class Teacher{
    public int TeacherId { getset; }
    public string Code { getset; }
    public string Name { getset; }
public class Student{
    public int StudentId { getset; }
    public string Code { getset; }
    public string Name { getset; }
    public string EnrollmentNo { getset; }
} 

The following are the methods that help us to get all the teachers and students.

private List<Teacher> GetTeachers(){
    List<Teacher> teachers = new List<Teacher>();
    teachers.Add(new Teacher { TeacherId = 1, Code = "TT", Name = "Tejas Trivedi" });
    teachers.Add(new Teacher { TeacherId = 2, Code = "JT", Name = "Jignesh Trivedi" });
    teachers.Add(new Teacher { TeacherId = 3, Code = "RT", Name = "Rakesh Trivedi" });
    return teachers;
public List<Student> GetStudents(){
    List<Student> students = new List<Student>();
    students.Add(new Student { StudentId = 1, Code = "L0001", Name = "Amit Gupta", EnrollmentNo = "201404150001" });
    students.Add(new Student { StudentId = 2, Code = "L0002", Name = "Chetan Gujjar", EnrollmentNo = "201404150002" });
    students.Add(new Student { StudentId = 3, Code = "L0003", Name = "Bhavin Patel", EnrollmentNo = "201404150003" });
    return students;
}

Required output



Solution

There are many ways to use multiple models with a single view. Here we will explain all the ways one by one.

1. Using Dynamic Model

ExpandoObject (the System.Dynamic namespace) is a class that was added to the .NET Framework 4.0 that allows us to dynamically add and remove properties onto an object at runtime. Using this ExpandoObject, we can create an new object and can add out list of teachers and students into it as a property. We can pass this dynamically created object to the view and render list of teacher and student.

Controller Code

public class HomeController : Controller{
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to my demo!";
        dynamic mymodel = new ExpandoObject();
        mymodel.Teachers = GetTeachers();
        mymodel.Students = GetStudents();
        return View(mymodel);
    }
}

We can define our model as dynamic (not a strongly type model) using the @model dynamic keyword.

View Code

@using MultipleModelInOneView;
@model dynamic
@{
    ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>

<p><b>Teacher List</b></p>

<table>
    <tr>
        <th>Id</th>
        <th>Code</th>
        <th>Name</th>
    </tr>
    @foreach (Teacher teacher in Model.Teachers)
    {
        <tr>
            <td>@teacher.TeacherId</td>
            <td>@teacher.Code</td>
            <td>@teacher.Name</td>
        </tr>
    }
</table>

<p><b>Student List</b></p>

<table>
    <tr>
        <th>Id</th>
        <th>Code</th>
        <th>Name</th>
        <th>Enrollment No</th>
    </tr>
    @foreach (Student student in Model.Students)
    {
        <tr>
            <td>@student.StudentId</td>
            <td>@student.Code</td>
            <td>@student.Name</td>
            <td>@student.EnrollmentNo</td>
        </tr>
    }
</table>

2. Using View Model

ViewModel is nothing but a single class that may have multiple models. It contains multiple models as a property. It should not contain any method.

In the above example, we have the required View Model with two properties. This ViewModel is passed to the view as a model. To get intellisense in the view, we need to define a strongly typed view.

public class ViewModel{
    public IEnumerable<Teacher> Teachers { getset; }
    public IEnumerable<Student> Students { getset; }
}

Controller Code

public ActionResult IndexViewModel(){
    ViewBag.Message = "Welcome to my demo!";
    ViewModel mymodel = new ViewModel();
    mymodel.Teachers = GetTeachers();
    mymodel.Students = GetStudents();
    return View(mymodel);
}

View Code

@using MultipleModelInOneView;@model ViewModel @{    ViewBag.Title = "Home Page";}<h2>@ViewBag.Message</h2> <p><b>Teacher List</b></p> <table>    <tr>        <th>Id</th>        <th>Code</th>        <th>Name</th>    </tr>    @foreach (Teacher teacher in Model.Teachers)
    {
        <tr>            <td>@teacher.TeacherId</td>            <td>@teacher.Code</td>            <td>@teacher.Name</td>        </tr>    }
</table> <p><b>Student List</b></p> <table>    <tr>        <th>Id</th>        <th>Code</th>        <th>Name</th>        <th>Enrollment No</th>    </tr>    @foreach (Student student in Model.Students)
    {
        <tr>            <td>@student.StudentId</td>            <td>@student.Code</td>            <td>@student.Name</td>            <td>@student.EnrollmentNo</td>        </tr>    }
</table>

3. Using ViewData

ViewData is used to transfer data from controller to the view. ViewData is a Dictionary object that may be accessible using a string as a key. Using ViewData, we can pass any object from the controller to the view. The Type Conversion is required when enumerating in the view. For the preceding example, we need to create ViewData to pass a list of teachers and students from the controller to the view.

Controller Code

public ActionResult IndexViewData(){
    ViewBag.Message = "Welcome to my demo!";
    ViewData["Teachers"] = GetTeachers();
    ViewData["Students"] = GetStudents();
    return View();
}

View Code

@using MultipleModelInOneView;@{    ViewBag.Title = "Home Page";}<h2>@ViewBag.Message</h2> <p><b>Teacher List</b></p> @{
   IEnumerable<Teacher> teachers = ViewData["Teachers"as IEnumerable<Teacher>;
   IEnumerable<Student> students = ViewData["Students"as IEnumerable<Student>;
}<table>    <tr>        <th>Id</th>        <th>Code</th>        <th>Name</th>    </tr>    @foreach (Teacher teacher in teachers)
    {
        <tr>            <td>@teacher.TeacherId</td>            <td>@teacher.Code</td>            <td>@teacher.Name</td>        </tr>    }
</table> <p><b>Student List</b></p>
<table>    <tr>        <th>Id</th>        <th>Code</th>        <th>Name</th>        <th>Enrollment No</th>    </tr>    @foreach (Student student in students)
    {
        <tr>            <td>@student.StudentId</td>            <td>@student.Code</td>            <td>@student.Name</td>            <td>@student.EnrollmentNo</td>        </tr>    }
</table>

4. Using ViewBag
ViewBag is similar to ViewData and also is used to transfer data from the controller to the view. ViewBag is dynamic property. ViewBag is just a wrapper around the ViewData.
Controller Code
public ActionResult IndexViewBag()
{
    ViewBag.Message = "Welcome to my demo!";
    ViewBag.Teachers = GetTeachers();
    ViewBag.Students = GetStudents();
    return View();
}

View Code

@using MultipleModelInOneView;
@{
    ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>

<p><b>Teacher List</b></p>

<table>
    <tr>
        <th>Id</th>
        <th>Code</th>
        <th>Name</th>
    </tr>
    @foreach (Teacher teacher in ViewBag.Teachers)
    {
        <tr>
            <td>@teacher.TeacherId</td>
            <td>@teacher.Code</td>
            <td>@teacher.Name</td>
        </tr>
    }
</table>

<p><b>Student List</b></p>

<table>
    <tr>
        <th>Id</th>
        <th>Code</th>
        <th>Name</th>
        <th>Enrollment No</th>
    </tr>
    @foreach (Student student in ViewBag.Students)
    {
        <tr>
            <td>@student.StudentId</td>
            <td>@student.Code</td>
            <td>@student.Name</td>
            <td>@student.EnrollmentNo</td>
        </tr>
    }
</table>

5. Using Tuple

A tuple is an immutable, fixed-size and ordered sequence object. It is a data structure that has a specific number and sequence of the elements. The .NET Framework supports tuples up to seven elements.

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

Controller Code

public ActionResult IndexTuple(){
    ViewBag.Message = "Welcome to my demo!";
    var tupleModel = new Tuple<List<Teacher>, List<Student>>(GetTeachers(), GetStudents());
    return View(tupleModel);
}

View Code

@using MultipleModelInOneView;@model Tuple <List<Teacher>, List <Student>>@{    ViewBag.Title = "Home Page";}<h2>@ViewBag.Message</h2> <p><b>Teacher List</b></p><table>    <tr>        <th>Id</th>        <th>Code</th>        <th>Name</th>    </tr>    @foreach (Teacher teacher in Model.Item1)
    {
        <tr>            <td>@teacher.TeacherId</td>            <td>@teacher.Code</td>            <td>@teacher.Name</td>        </tr>    }
</table>
<p><b>Student List</b></p>
<table>    <tr>        <th>Id</th>        <th>Code</th>        <th>Name</th>        <th>Enrollment No</th>    </tr>    @foreach (Student student in Model.Item2)
    {
        <tr>            <td>@student.StudentId</td>            <td>@student.Code</td>            <td>@student.Name</td>            <td>@student.EnrollmentNo</td>        </tr>    }
</table>

6. Using Render Action Method

A Partial View defines or renders a view within a view. We can render some part of a view by calling a controller action method using the Html.RenderAction method. The RenderAction method is very useful when we want to display data in the partial view. The disadvantages of this method is that there are only multiple calls of the controller.

In the following example, I have created a view (named, partialView.cshtml) and within this view I called the html.RenderAction method to render the teacher and the student list.

Controller Code

public ActionResult PartialView()
{
    ViewBag.Message = "Welcome to my demo!";
    return View();
}

/// <summary>
/// Render Teacher List
/// </summary>
/// <returns></returns>
public PartialViewResult RenderTeacher()
{
    return PartialView(GetTeachers());
}

/// <summary>
/// Render Student List
/// </summary>
/// <returns></returns>
public PartialViewResult RenderStudent()
{
    return PartialView(GetStudents());
}

View Code

@{   ViewBag.Title = "PartialView";<h2>@ViewBag.Message</h2><div>    @{        Html.RenderAction("RenderTeacher");
        Html.RenderAction("RenderStudent");
    }
</div>

RenderTeacher.cshtml

@using MultipleModelInOneView;@model IEnumerable<MultipleModelInOneView.Teacher>
 
<p><b>Teacher List</b></p><table>    <tr>        <th>Id</th>        <th>Code</th>        <th>Name</th>    </tr>    @foreach (Teacher teacher in Model)
    {
        <tr>            <td>@teacher.TeacherId</td>            <td>@teacher.Code</td>            <td>@teacher.Name</td>        </tr>    }
</table>

RenderStudent.cshtml

@using MultipleModelInOneView;@model IEnumerable<MultipleModelInOneView.Student
<p><b>Student List</b></p><table>    <tr>        <th>Id</th>        <th>Code</th>        <th>Name</th>        <th>Enrollment No</th>    </tr>    @foreach (Student student in Model)
    {
        <tr>            <td>@student.StudentId</td>            <td>@student.Code</td>            <td>@student.Name</td>            <td>@student.EnrollmentNo</td>        </tr>    }
</table>


Conclusion 

This article help us to learn how to pass multiple models from the controller to the the view. I hope this will be helpful for beginners.