On my last tutorial on Controllers in ASP.NET Core I tough about Controller. A controller contains Action methods, they can have any return type like string, int, datetime, ViewResult, IActionResult etc. In all of them the return type of IActionResult is quite useful.
When the return type of action method is IActionResult or ViewResult then it can tell MVC to render a given View. This is done by the View() method.
The given action method is telling MVC to return a View which in this case is the Index View.
public IActionResult Index() { return View(); }
The View() method has 4 different versions which are described in the below table:
Method | Description |
---|---|
View() |
Targets the default View for the MVC to render it. Eg if the action method name is List and you are using the View() method then the List.cshtml view will be rendered. |
View("name_of_view") |
This version takes the view name in its parameter and this view will be rendered. Eg if you use View("Show") then the show.cshtml view will be rendered |
View(model) |
This version will render the default view by providing it with model data (class data). This is used to make the rendered view strongly typed. |
View("name_of_view", model) |
This version specifies the View by it’s name along with the model data that it will be provided with. |
Page Contents
There are 4 different ways of passing data from Action Method to a View. These are:
1. View Model Object
2. ViewBag
3. TempData
4. Session Variable
Previously I explained the View() method to you. This method is used to send an object to the View. To understand it, create a new Controller and name it Example and let its Index Action returns current date & time (by DateTime.Now) as shown below:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; namespace UnderstandingControllersViews.Controllers { public class ExampleController : Controller { public IActionResult Index() { return View(DateTime.Now); } } }
I have passed DateTime object to the View. Now create Index View inside the Views ➤ Example folder with the code as given below. Notice I am displaying the date & time value contained in the model like @Model
(as it is returned by the Action method).
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> </head> <body> Model: @Model and Year: @(((DateTime)Model).Date) </body> </html>
Now to display the current Year my code is – @(((DateTime)Model).Date). This is because I have to cast the Model to DateTime first only then I can extract the Date from it.
Run the application and go to – https://localhost:44339/Example. You will see the Date Time and Current Year displayed on the browser as shown in the below image.
This is an Untyped View or Weakly Typed View. The View has no prior knowledge about the View Model Object it will be receiving from the Action. So I have to cast it to an instance of DateTime.
I can make this view Strongly Typed View by telling the View the type of the View Model Object it will be receiving from the Action. This is done by adding – @model DateTime
The below highlighted code makes my View strongly typed:
@model DateTime @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> </head> <body> Model: @Model and Year: @Model.Year </body> </html>
Notice I defined the View Model Object by – @model DateTime.
Now I can simply display the current year as – @Model.Year without having to cast it.
In the same way you can also send View Model Object of type String, class, bool, etc.
If you are passing string from action to view then cast your string to Object, like this way:
retrun View((object)"How are you");
The reason for this is because if the parameter of the View() method is a string then it will search for the view with the same name as the provided string. To avoid this thing you need to cast your string to an object.
View Bag allows to define properties on a dynamic object. These properties can then be accessed in Views. This dynamic object can be accessed through the ViewBag property.
Create a new action by name ViewBagExample in the Example Controller having code shown below:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; namespace UnderstandingControllersViews.Controllers { public class ExampleController : Controller { public IActionResult Index() { return View(DateTime.Now); } public IActionResult ViewBagExample() { ViewBag.CurrentDateTime = DateTime.Now; ViewBag.CurrentYear = DateTime.Now.Year; return View(); } } }
I have added 2 properties – CurrentDateTime & CurrentYear to the ViewBag variable. These contains the current datetime and current year.
Now on my View I can simply access these values like ViewBag.CurrentDateTime & ViewBag.CurrentYear. See the below code of the view called ViewBagExample:
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>ViewBagExample</title> </head> <body> Model: @ViewBag.CurrentDateTime and Year: @ViewBag.CurrentYear </body> </html>
Now run the application and go to the URL – https://localhost:44339/Example/ViewBagExample, it will give the same display like before.
You know that ViewBag values are lost in case there is a redirection therefore for such cases you use TempDate. TempData is similar to ViewBag except that its values live during redirection also.
Like ViewBag MVC automatically removes the values of the TempData as soon as they are read.
Let’s add 2 new actions in the Example Controller. These have the names – TempDataExample & TempDataShow. The codes for these 2 actions are given below:
public IActionResult TempDataExample() { TempData["CurrentDateTime"] = DateTime.Now; TempData["CurrentYear"] = DateTime.Now.Year; return RedirectToAction("TempDataShow"); } public IActionResult TempDataShow() { return View(); }
The action called TempDataExample adds the current datetime and current year to 2 TempDate properties:
It then redirects to the TempDataShow action using the RedirectToAction method as shown below:
return RedirectToAction("TempDataShow");
The TempDataShow view just invokes the default View.
Now create the TempDataShow View inside the Views ➤ Example folder. Then add the below code to it:
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>TempDataShow</title> </head> <body> Model: @TempData["CurrentDateTime"] and Year: @TempData["CurrentYear"] </body> </html>
TempData stores values in dictionary manner so I am accessing these values using brackets ‘[]’.
Note that TempData relies on Session Middleware therefore you have to add services.AddSession() to the ConfigureServices() method of Startup.cs class.
The highlighted lines in the below code tells what you have to add to the Startup class.
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace UnderstandingControllersViews { public class Startup { // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddSession(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { //... } } }
The AddSession methods create services required by session
management.
Now run the application and go to the URL – https://localhost:44339/Example/TempDataExample, it will show the current datetime and year, like the View Model Object example above.
Note: We can’t use ViewBag in this case as Viewbag values gets lost during redirection. You can check it by replacing the TempData with ViewBag in the TempDataShow View and the TempDataExample action.
The ‘Peek’ method allows you to get the value and also prevent it from deletion. This is because it does not tells MVC that the value has been read.
Use session to store the value permanently (until the session expires) for as many reads as you want and in any part of the application.
Session state is a storage of data while the user browses a website. Session state uses a store maintained by the app to persist data across requests from a client. You can use the data stored in the Session variable anywhere in your website.
You can enable the session for the application by adding services.AddSession()
in the ConfigureServices() method and app.UseSession()
in the Configure() method of the Startup class. I have highlighted this in the below code:
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddSession(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseSession(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); } }
Let us understand how Session State works. Create a new action called SessionExample inside the Example Controller with codes given below:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace UnderstandingControllersViews.Controllers { public class ExampleController : Controller { // removed for simplicity public IActionResult SessionExample() { HttpContext.Session.SetString("CurrentDateTime", DateTime.Now.ToString()); HttpContext.Session.SetString("CurrentYear", DateTime.Now.Year.ToString()); return View(); } } }
To use session in controller class, you need to reference the Microsoft.AspNetCore.Http namespace in the controller.
The SetString() method will add any value as string to the session variable. In my case I am adding the current datetime and year as string to the 2 session variables.
To access the session’s variable value in the view you have to add a singleton service to the ConfigureServices() method of Startup.cs as shown below
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddSession(); services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); }
Now create the SessionExample View inside the Views ➤ Example folder and add the following code to it:
@using Microsoft.AspNetCore.Http @inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>SessionExample</title> </head> <body> Model: @HttpContextAccessor.HttpContext.Session.GetString("CurrentDateTime") and Year: @HttpContextAccessor.HttpContext.Session.GetString("CurrentYear") </body> </html>
I have included the namespace Microsoft.AspNetCore.Http just like the controller. Then injected my singleton object through the inject directive using ASP.NET Core Dependency Injection.
Finally I access the session values using @HttpContextAccessor.HttpContext.Session.GetString().
Run the application and go to the URL – https://localhost:44339/Example/SessionExample to see the current datetime and year displayed by the view.
Just like the SetString() method the session also has SetInt32() which stores the int value in the session variable:
HttpContext.Session.SetInt32("MySession", 100);
To store complex data types like class variable in the session you have to first serialize them. Then to get the serialized value from session you have to De-serialize them.
To do this add the following extension methods to set and get serializable objects
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Newtonsoft.Json; namespace UnderstandingControllersViews.Models { public static class SessionExtensions { public static void Set<T>(this ISession session, string key, T value) { session.SetString(key, JsonConvert.SerializeObject(value)); } public static T Get<T>(this ISession session, string key) { var value = session.GetString(key); return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value); } } }
Then in your C# code you can do these things:
// Setting the session value HttpContext.Session.Set<Person>("MyPersonClass", person); // Getting the session value HttpContext.Session.Get<Person>("MyPersonClass");
Session’s cookie name and expiration time can be set inside the services.AddSession() method as shown below:
services.AddSession(options => { options.Cookie.Name = "AdventureWorks.Session"; // Cookie name options.IdleTimeout = TimeSpan. FromHours(1); // 1 hours expiry });
There are many ways to perform redirection from an action method to another action method. There are many methods for it like:
1. Redirect
2. RedirectPermanent
3. RedirectToRoute
4. RedirectToRoutePermanent
5. RedirectToAction
6. RedirectToActionPermanent
The Redirect method is used to perform a temporary redirection (HTTP 302). It takes the redirection URL as a string argument and returns an instance of the RedirectResult class.
Example: The below Action method by the name of RedirectAction performs a temporary redirect to URL – /List/Search.
public RedirectResult RedirectAction() => Redirect("/List/Search");
RedirectPermanent method is similar to Redirect method except it redirects user permanently (HTTP 301).
Example: This time the action method by the name of RedirectAction performs a permanent redirect to URL – /List/Search.
public RedirectResult RedirectAction() => RedirectPermanent("/List/Search");
If you want to redirect user by following the routes of your application then you should use RedirectToRoute() method. It performs temporary redirection and takes an anonymous type as parameter. The properties of the anonymous type are then passed to the routing system to generate a URL.
The RedirectToRoute() method returns an instance of the RedirectToRouteResult.
Let’s take an example. My application has the route:
app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); });
To perform based on this route I can use the RedirectToRoute() method as shown below:
public RedirectToRouteResult Redirect() { RedirectToRoute(new { controller = "Admin", action = "Users", ID = "10" }); }
So it will redirect user to – /Admin/Users/10.
The RedirectToRoutePermanent similar to RedirectToRoute method except it redirects user permanently.
Example:
public RedirectToRouteResult Redirect() { RedirectToRoutePermanent(new { controller = "Admin", action = "Users", ID = "10" }); }
The RedirectToAction method performs temporary redirection to a given action method.
This method returns an instance of RedirectToActionResult class.
The redirect URL is formed based on the routes of your application.
Consider that my application route is:
app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); });
Now consider you apply RedirectToAction() method on the Index View as shown in the below code:
public class HomeController : Controller { public RedirectToActionResult Index() { return RedirectToAction("List"); } public RedirectToActionResult List() { return View(); } }
So this will redirect user (based on the routes) to the URL – /Home/List.
If you give just an action method, then ASP.NET Core assumed that you are referring to an action method in the current controller.
So to redirect to the action of a different Controller you need to specify the Controller name also. In the below code I am redirecting to the List action of Customer controller:
public RedirectToActionResult Index() { return RedirectToAction("Customer","List"); }
The RedirectToActionPermanent method performs permanent redirection. In all other cases it is similar to RedirectToAction method.
Example:
public RedirectToActionResult Index() { return RedirectToActionPermanent("List"); }
So far you have seen Action method returning string and View. But these are not the only things. In fact Actions Methods can return JSON and HTTP Status codes also. The below topics teaches you these methods.
The method Json() returns JSON (JavaScript Object Notation) objects from Action methods. This method returns an object of JsonResult class.
The action method called ReturnJson located in the ExampleController return a JSON:
public JsonResult ReturnJson() { return Json(new[] { "Brahma", "Vishnu", "Mahesh" }); }
Create the View called ReturnJson.cshtml inside the Views ➤ Example folder and show the JSON with @Model. The full code of this view is given below:
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>ReturnJson</title> </head> <body> @Model </body> </html>
To test it run the application and go to the URL – https://localhost:44339/Example/ReturnJson. You will see the JSON as shown in the given image:
The OK method produces an empty HTTP Status Code 200 responses. It can be used to return objects in common format between the browser and the application with HTTP 200 status code.
The return type of this method is OkObjectResult class.
Example:
public OkObjectResult ReturnOk() { return Ok(new string[] { "Brahma", "Vishnu", "Mahesh" }); }
In the View you can simply show the model data as @Model
.
To return just an HTTP 200 status code without any data simply use an empty Ok() method.
The StatusCode method that resides inside the Microsoft.AspNetCore.Http namespace is used to return any type of status codes like BadRequest, Unauthorized, NotFound, etc.
The return type of this method is StatusCodeResult class of Microsoft.AspNetCore.Mvc namespace.
public StatusCodeResult ReturnBadRequst() { return StatusCode(StatusCodes.Status400BadRequest); }
public StatusCodeResult ReturnUnauthorized() { return StatusCode(StatusCodes.Status401Unauthorized); }
public StatusCodeResult ReturnNotFound() { return StatusCode(StatusCodes.Status404NotFound); //or return NotFound(); }
You can download the full codes of this tutorial from the below link:
In this tutorial I explained Action Methods and their usage in Controllers. I hope you find it useful.
I will continue with Views in my next tutorial – Views in ASP.NET Core
Share this article -