Passing Data From Controller To View With TempData - Part Four

This article will tell you almost everything you need to know about passing data from Controller to View in ASP.NET MVC using TempData. I am writing this article to tell you the basic to advanced foremost concepts about ways to pass data from Controller to View. This article is the fourth one in the series named “Passing Data from Controller to View”. You’ll learn all the ways in each separate article. Stay tuned!

I would strongly recommend reading my previous articles, which will be defining the basic concepts of ASP.NET MVC.

Especially, read my consecutive previous articles in which I have taught the way of passing the data from Controller to View using ViewBag. This is the link to the previous article. Read this article, check the code after downloading, and then feel free to give your feedback.

The topics to be covered are.

  1. What is TempData?
  2. Passing the data from Controller to View using TempData
  3. Differing features of TempData from ViewBag and ViewData
  4. Maintaining the State of TempData to multiple requests

Introduction

As we know Controller is the class that is responsible for handling all the HTTP requests and then executing the appropriate View. And View gives us the HTML markup that we display to the user. And for displaying anything on the View, there should be some data that is passed from Controller to View. And in this and next articles, you will learn how to pass data from Controller to View.

In this article, you’ll learn how to pass strongly typed data from Controller to View using TempData. And, you’ll see other ways to pass data, in coming articles. So stay tuned!

What is TempData?

TempData is the same as ViewBag and ViewData but also has more functionalities. It is actually a dictionary having a type TempDataDictionary and it is used to store the temporary data. TempData is also one of the properties of the “ControllerBase” class so when we create a controller, that controller will automatically inherit the “Controller” abstract class and this “Controller” class inherits the “ControllerBase” abstract class, that’s why we can access this TempData property in each controller. You can see in the image below the “Controller” class which inherits the “ControllerBase” class.

TempData

And in the “ControllerBase” class, the TempData property is defined, see its syntax below.

namespace System.Web.Mvc
{
    /// <summary>Represents the base class for all MVC controllers.</summary>
    public abstract class ControllerBase : IController
    {
        // Other code is removed for clarity.

        /// <summary>Gets or sets the dictionary for temporary data.</summary>
        /// <returns>The dictionary for temporary data.</returns>
        public TempDataDictionary TempData { get; set; }
    }
}

TempData is a constraint in which we maintain the state of consecutive requests. It internally uses session variables. But we do not need to clear these variables for TempData, it automatically clears its session variables. It requires typecasting for passing complex data and checking for null values to avoid errors. Let’s look at its main and simple functionality with the help of an example.

Passing the data from Controller to View using TempData

To pass the strongly typed data from Controller to View using TempData, we have to make a model class then populate its properties with some data and then pass that data to TempData as Value and selecting Key’s name is the programmer’s choice. And then in the View, we can access the data of model class by using TempData with the pre-defined keys. Let’s create a project to take a look at an example.

Go to File then New and select the “Project” option.

View

Then create the ASP.NET web application project as depicted below.

ASP.NET

Then select “Empty” and tick “MVC” then click OK.

MVC

The project is created successfully.

Now create a class named “Employee” in the Models folder, shown below.

Employee

Visual C#

Now add some properties into this class as the code is given below.

namespace DataCtoV.Models
{
    public class Employee
    {
        [Display(Name = "Serial No")]
        public byte EmployeeId { get; set; }
        [Display(Name = "Name")]
        public string EmployeeName { get; set; }
        public string Address { get; set; }
        public string Phone { get; set; }
    }
}

Now, we’ll add a controller from where this data of an employee will pass. Let’s create a Controller, as shown below.

 Controller

Then, select “MVC 5 Controller– Empty” and click Add.

Empty

Then give the name of the Controller and click on Add.

Add

The Controller is created successfully. In this Controller, we’ll make an action method with the name of “GetEmployeeData” in which we’ll make an object of the “Employee” model class and populate this object with some data. Then pass this object to the TempData with the help of a key named “employee”. The code of “EmployeeDataController” is given below.

namespace DataCtoV.Controllers
{
    public class EmployeeDataController : Controller
    {
        // GET: EmployeeData
        public ActionResult GetEmployeeData()
        {
            List<Employee> emp = new List<Employee>
            {
                new Employee
                {
                    EmployeeId = 1,
                    EmployeeName = "John",
                    Address = "12 Fremont St. Clermont, FL 2813",
                    Phone = "+1-234-2838421"
                },
                new Employee
                {
                    EmployeeId = 2,
                    EmployeeName = "Smith",
                    Address = "14 Highland Drive Fort Worth, TX 3994",
                    Phone = "+1-234-2244521"
                },
                new Employee
                {
                    EmployeeId = 3,
                    EmployeeName = "Marry",
                    Address = "23 Fremont Road Milledgeville, GA 6788",
                    Phone = "+1-234-46568421"
                }
            };

            TempData["employee"] = emp;

            return View();
        }
    }
}

Because we don’t have any View named “GetEmployeeData” in the Views folder, let’s create it. For creating a View, right-click on the “GetEmployeeData” method and select the “Add View…” option. The following dialogue box will open, click on “Add”

GetEmployeeData

The View is created successfully. Let’s write the code for it.

@using DataCtoV.Models
@model IEnumerable<DataCtoV.Models.Employee>

@{
    ViewBag.Title = "Employee Data";
}

<h3>Employee Data</h3>
<table class="table table-condensed table-hover">
    <thead>
        <tr>
            <th>@Html.DisplayNameFor(e => e.EmployeeId)</th>
            <th>@Html.DisplayNameFor(e => e.EmployeeName)</th>
            <th>@Html.DisplayNameFor(e => e.Address)</th>
            <th>@Html.DisplayNameFor(e => e.Phone)</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var employee in (IEnumerable<Employee>)TempData["employee"])
        {
            <tr>
                <td>@employee.EmployeeId</td>
                <td>@employee.EmployeeName</td>
                <td>@employee.Address</td>
                <td>@employee.Phone</td>
            </tr>
        }
    </tbody>
</table>

You can see in the code that, we have made a table to represent the strongly typed data of the Employee model class. We have used a foreach loop to iterate the data of each employee passed from the Controller.

To iterate the data, here we have used TempData which is calling the data from the Controller with the help of a key named “employee”. And you can also see that we must have to cast the TempData to Employee.

Note. We must have to cast the TempData before using it.

Why casting?

Casting

As we know, TempData has the type TempDataDictionary and this Dictionary has the type “object”, and the for each loop cannot accept variables having the type “object”. In the object type, the theGetEnumerator method is not defined that’s why we can’t iterate the data of Employee’s collection.

To iterate the data of Employee’s collection properly, we have to cast it to IEnumerable because there a list/collection of Employees is coming, and only in IEnumerable, the GetEnumerator is defined for iterating it properly. Hence we must cast it in theforeach loop. See the Error below without casting.

 IEnumerable

Ways of Casting

One way of casting the TempData is described above, which is at a time casting of TempData in the foreach loop. The code is given below.

 Code

Another way of casting the TempData is, to cast the TempData in the Multi-Statement Razor Code block for C#, and then use the variable in the foreach loop. You can see the code below.

Casting in the code block.

@{
    ViewBag.Title = "Employee Data";
    var employeeData = (IEnumerable<Employee>)TempData["employee"];
}

Then, use the “employee data” variable in the foreach loop, as shown below.

@foreach (var employee in employeeData)
{
    <tr>
        <td>@employee.EmployeeId</td>
        <td>@employee.EmployeeName</td>
        <td>@employee.Address</td>
        <td>@employee.Phone</td>
    </tr>
}

All the code of the “GetEmployeeData” View is given below for your convenience.

@using DataCtoV.Models
@model IEnumerable<DataCtoV.Models.Employee>

@{
    ViewBag.Title = "Employee Data";
    var employeeData = (IEnumerable<Employee>)TempData["employee"];
}

<h3>Employee Data</h3>
<table class="table table-condensed table-hover">
    <thead>
        <tr>
            <th>@Html.DisplayNameFor(e => e.EmployeeId)</th>
            <th>@Html.DisplayNameFor(e => e.EmployeeName)</th>
            <th>@Html.DisplayNameFor(e => e.Address)</th>
            <th>@Html.DisplayNameFor(e => e.Phone)</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var employee in employeeData)
        {
            <tr>
                <td>@employee.EmployeeId</td>
                <td>@employee.EmployeeName</td>
                <td>@employee.Address</td>
                <td>@employee.Phone</td>
            </tr>
        }
    </tbody>
</table>

You have seen the reason for casting and ways to do casting. Now simply, let’s build and run the application. You should see the following output.

 Output

Hence you have seen the practical example of TempData. Now let’s move towards its more features.

Differing features of TempData from ViewBag and ViewData

TempData is a container in which we maintain the state of consecutive requests. It internally uses session variables but we do not need to clear these variables for TempData, it automatically clears its session variables. TempData stores the information only for an HTTP request mean to say from one page to another. TempData also works with 302 (Found) redirection and 301 (See Other) redirection because it’s in the same HTTP request. TempData helps to maintain the data from one controller/action to another controller/action. You may say when you redirect, theTempData helps to maintain data between these redirects. Now, look at a practical example in which the redirection occurs.

For this, first, you have to make some changes in the “GetEmployeeData.cshtml” View. Comment all the code and write the following line of code.

@{
    ViewBag.Title = "Employee Data";
} 
<br />
@Html.ActionLink("Click for Redirection", "SecondMethod", "EmployeeData")

The above line of code makes the redirection from the “GetEmployeeData” action method to the “SecondMethod” action method to show you that the TempData supports redirection while maintaining the data.

Now, you have to make another action method in the “EmployeeDataController” controller named “SecondMethod”. The complete code of “EmployeeDataController” after making changes is as follows.

namespace DataCtoV.Controllers
{
    public class EmployeeDataController : Controller
    {
        // GET: EmployeeData
        public ActionResult GetEmployeeData()
        {
            List<Employee> emp = new List<Employee>
            {
                new Employee
                {
                    EmployeeId = 1,
                    EmployeeName = "John",
                    Address = "12 Fremont St. Clermont, FL 2813",
                    Phone = "+1-234-2838421"
                },
                new Employee
                {
                    EmployeeId = 2,
                    EmployeeName = "Smith",
                    Address = "14 Highland Drive Fort Worth, TX 3994",
                    Phone = "+1-234-2244521"
                },
                new Employee
                {
                    EmployeeId = 3,
                    EmployeeName = "Marry",
                    Address = "23 Fremont Road Milledgeville, GA 6788",
                    Phone = "+1-234-46568421"
                }
            };

            TempData["employee"] = emp;
            // We have to use keep function if we want to print data at 
            // "GetEmployeeData.cshtml"
            TempData.Keep();

            return View();
        }

        public ActionResult SecondMethod()
        {
            // The second method is used to show redirection in TempData.
            ViewBag.emp = TempData["employee"];
            return View();
        }
    }
}

Now, we have to make the SecondMethod.cshtml view file in the Views folder. After making, the code will be as shown below.

@model DataCtoV.Models.Employee
@{
    ViewBag.Title = "Second";
}

<h2>Second</h2>

<table class="table table-condensed table-hover">
    <thead>
        <tr>
            <th>@Html.DisplayNameFor(e => e.EmployeeId)</th>
            <th>@Html.DisplayNameFor(e => e.EmployeeName)</th>
            <th>@Html.DisplayNameFor(e => e.Address)</th>
            <th>@Html.DisplayNameFor(e => e.Phone)</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var employee in ViewBag.emp)
        {
            <tr>
                <td>@employee.EmployeeId</td>
                <td>@employee.EmployeeName</td>
                <td>@employee.Address</td>
                <td>@employee.Phone</td>
            </tr>
        }
    </tbody>
</table>

Now, simply build and run the application for this URL - /EmployeeData/GetEmployeeData. You should see the following output.

URL

When you click on the link, you will be redirected from the “GetEmployeeData” action method to the “SecondMethod” action method. And the output will be like below.

SecondMethod

Hence you have seen the redirection while maintaining data using TempData. This is the feature that makes TempData different from ViewBag and ViewData because this feature is not present in ViewBag and ViewData.

Maintaining the State of TempData to multiple requests

In the previous section, you maintained the state of data at the first request and made values accessible at the second request. Now if you want to maintain the state up to third, fourth, and so on requests, then how can you do it?

This can be done by using a built-in “Keep” function with the TempData variables. Let’s look at its practical example by making some changes to the “DataCtoV” project. So we make changes in “SecondMethod” by using the “Keep” function to maintain the state of data.

public ActionResult SecondMethod()
{
    // The second method is used to show redirection in TempData.
    ViewBag.emp = TempData["employee"];
    
    // To maintain the state of TempData
    TempData.Keep();
    
    return View();
}

Then go to its View named as “SecondMethod.cshtml” and add the following line of code to enable the redirection of the request.

@Html.ActionLink("Click for 2nd redirection", "ThirdMethod", "EmployeeData")

And then, add another action method named “ThirdMethod” into the “EmployeeDataController”. The code of “ThirdMethod” is as follows.

public ActionResult ThirdMethod()
{
    // The third method is used to show redirection and maintaining data up to multiple requests in TempData.
    ViewBag.third = TempData["employee"];
    return View();
}

Now, create its view and place the following code in it.

@model DataCtoV.Models.Employee  
@{  
    ViewBag.Title = "ThirdMethod";  
}  

<h2>ThirdMethod</h2>  

<table class="table table-condensed table-hover">  
    <thead>  
        <tr>  
            <th>@Html.DisplayNameFor(e => e.EmployeeId)</th>  
            <th>@Html.DisplayNameFor(e => e.EmployeeName)</th>  
            <th>@Html.DisplayNameFor(e => e.Address)</th>  
            <th>@Html.DisplayNameFor(e => e.Phone)</th>  
        </tr>  
    </thead>  
    <tbody>  
        @foreach (var employee in ViewBag.third)  
        {  
            <tr>  
                <td>@employee.EmployeeId</td>  
                <td>@employee.EmployeeName</td>  
                <td>@employee.Address</td>  
                <td>@employee.Phone</td>  
            </tr>  
        }  
    </tbody>  
</table>

Now, I am providing the full code of each file only for your convenience.

The complete code of the “Employee” model class is as below.

namespace DataCtoV.Models
{
    public class Employee
    {
        [Display(Name = "Serial No")]
        public byte EmployeeId { get; set; }
        [Display(Name = "Name")]
        public string EmployeeName { get; set; }
        public string Address { get; set; }
        public string Phone { get; set; }
    }
}

The complete code of “EmployeeDataController” is given below.

namespace DataCtoV.Controllers
{
    public class EmployeeDataController : Controller
    {
        // GET: EmployeeData
        public ActionResult GetEmployeeData()
        {
            List<Employee> emp = new List<Employee>
            {
                new Employee
                {
                    EmployeeId = 1,
                    EmployeeName = "John",
                    Address = "12 Fremont St. Clermont, FL 2813",
                    Phone = "+1-234-2838421"
                },
                new Employee
                {
                    EmployeeId = 2,
                    EmployeeName = "Smith",
                    Address = "14 Highland Drive Fort Worth, TX 3994",
                    Phone = "+1-234-2244521"
                },
                new Employee
                {
                    EmployeeId = 3,
                    EmployeeName = "Marry",
                    Address = "23 Fremont Road Milledgeville, GA 6788",
                    Phone = "+1-234-46568421"
                }
            };

            TempData["employee"] = emp;

            return View();
        }

        public ActionResult SecondMethod()
        {
            // The second method is used to show redirection in TempData.
            ViewBag.emp = TempData["employee"];

            // To maintain the state of TempData
            TempData.Keep();

            return View();
        }

        public ActionResult ThirdMethod()
        {
            // The third method is used to show redirection and maintaining data up to multiple requests in TempData.
            ViewBag.third = TempData["employee"];
            return View();
        }
    }
}

The complete code of the “GetEmployeeData.cshtml” view is as below.

@using DataCtoV.Models
@model IEnumerable<DataCtoV.Models.Employee>
@{
    ViewBag.Title = "Employee Data";
    var employeeData = (IEnumerable<Employee>)TempData["employee"];
}

<h3>Employee Data</h3>
<br />

@Html.ActionLink("Click for first Redirection", "SecondMethod", "EmployeeData")

<table class="table table-condensed table-hover">
    <thead>
        <tr>
            <th>@Html.DisplayNameFor(e => e.EmployeeId)</th>
            <th>@Html.DisplayNameFor(e => e.EmployeeName)</th>
            <th>@Html.DisplayNameFor(e => e.Address)</th>
            <th>@Html.DisplayNameFor(e => e.Phone)</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var employee in employeeData)
        {
            <tr>
                <td>@employee.EmployeeId</td>
                <td>@employee.EmployeeName</td>
                <td>@employee.Address</td>
                <td>@employee.Phone</td>
            </tr>
        }
    </tbody>
</table>

The complete code of “SecondMethod” as as follows.

@model DataCtoV.Models.Employee   
@{   
    ViewBag.Title = "Second";   
}   

<h2>Second</h2>   

@Html.ActionLink("Click for 2nd redirection", "ThirdMethod", "EmployeeData")   

<table class="table table-condensed table-hover">   
    <thead>   
        <tr>   
            <th>@Html.DisplayNameFor(e => e.EmployeeId)</th>   
            <th>@Html.DisplayNameFor(e => e.EmployeeName)</th>   
            <th>@Html.DisplayNameFor(e => e.Address)</th>   
            <th>@Html.DisplayNameFor(e => e.Phone)</th>   
        </tr>   
    </thead>   
    <tbody>   
        @foreach (var employee in ViewBag.emp)   
        {   
            <tr>   
                <td>@employee.EmployeeId</td>   
                <td>@employee.EmployeeName</td>   
                <td>@employee.Address</td>   
                <td>@employee.Phone</td>   
            </tr>   
        }   
    </tbody>   
</table>

The complete code of “ThirdMethod” is as follows.

@model DataCtoV.Models.Employee
@{
    ViewBag.Title = "ThirdMethod";
}

<h2>ThirdMethod</h2>

<table class="table table-condensed table-hover">
    <thead>
        <tr>
            <th>@Html.DisplayNameFor(e => e.EmployeeId)</th>
            <th>@Html.DisplayNameFor(e => e.EmployeeName)</th>
            <th>@Html.DisplayNameFor(e => e.Address)</th>
            <th>@Html.DisplayNameFor(e => e.Phone)</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var employee in ViewBag.third)
        {
            <tr>
                <td>@employee.EmployeeId</td>
                <td>@employee.EmployeeName</td>
                <td>@employee.Address</td>
                <td>@employee.Phone</td>
            </tr>
        }
    </tbody>
</table>

Now, simply build and run the application with the URL /EmployeeData/GetEmployeeData to see the output. Output should be as follows.

Run the application

Just click on the link “Click for the first Redirection” then its corresponding HTTP request will execute and give the following output.

HTTP

Above is the first redirection in which the state of TempData is maintained. This data will pass to “ThirdMethod” after clicking on the link “Click for 2nd redirection” Then the output will be like this.

Localhost

Hence in this way, you can maintain the state of TempData up to multiple requests.

Summary

In this article, you have learned how to pass strongly typed data from Controller to View using TempData, in which firstly, you should make a model class populate its properties with some data then pass that object to the TempData as Value and pass magic Key as a string. Then you have looked at the main differing features of TempData with ViewBag and ViewData. Also, you have learned how to maintain the state of TempData up to multiple requests.

Conclusion

I hope this article has helped you in understanding the concepts about passing strongly typed data from Controller to View using TempData in ASP.NET MVC. Stay tuned for my next articles because this article is the fourth one in the series of “Passing data from Controller to View” and you’ll learn more about passing data in coming articles. If you have any query, please feel free to contact me in the comments section. Also, do provide feedback whether positive or negative. It will help me to make my articles better and increase my enthusiasm to share my knowledge.


Similar Articles