Introduction
This article will demonstrate the basic to advanced concepts of action results in ASP.NET MVC. Last week, one of my friends asked the question, “Why is there a ContentResult data type in the action method, and what is its purpose?” I am dedicating this article to him. I hope he will like this.
The topics to be covered are
- What is ActionResult?
- Content Returning Results
- Status Results
The Question
The first part of the question is, "Why is there a ContentResult data type in the action method?". To understand this, you have to understand the data types in ASP.NET MVC 5 because the ContentResult is a data type whose base data type is ActionResult. Hence, you have to understand the Action Result.
Let’s get started with Action Result.
Action result in ASP.NET MVC
Action Result is a data type. When it is used with an action method, it is called return type. As you know, an action is referred to as a method of the controller, the Action Result is the result of the action when it executes. Action Result is a return type. This return type has many other derived types. First, look at the base and derived types of ActionResult.
namespace System.Web.Mvc
{
public abstract class ActionResult
{
//
// Summary:
// Initializes a new instance of the System.Web.Mvc.ActionResult class.
protected ActionResult();
}
}
As we see in the Visual Studio, the ActionResult type is coming from System.Web.Mvc assembly. The problem is that we can’t see inside this assembly with the “Go to Definition” feature of Visual Studio.
To see inside the assembly, you can either follow the following steps after downloading ILSpy, or you can watch this video by clicking here.
The steps are as follows.
- I am giving you the direct link to download the ILSpy. Click here.
- If you don’t have the System.Web.Mvc assembly, then you can download it after clicking here.
- Run ILSpy after extracting it.
- Click on File (on the top-left-corner)
- Select the “Open” option and open the assembly from where you downloaded it.
- After selecting, the assembly will load in ILSpy software.
- Expand the assembly, you will see ActionResult, expand it also, you will see the base and derived types.
- The types of ActionResult are shown in the image below.
Now, you can see that the Action Result is a base data type whose derived types are HttpStatusCodeResult, JavaScriptResult, FileResult, ContentResult, JsonResult, EmptyResult, RedirectResult, RedirectToRouteResult, ViewResult. And, there must be a helper method against each data type (either base or derived type).
When we go into ActionResult, we see that it is an abstract class.
namespace System.Web.Mvc
{
public abstract class ActionResult
{
//
// Summary:
// Initializes a new instance of the System.Web.Mvc.ActionResult class.
protected ActionResult();
}
}
It is an abstract class because the actions of the controller can return different types of data at the same time. So, it has to be abstract so that every HTTP request can be handled properly. See the code below.
public ActionResult Index()
{
bool answer = DateTime.Now.Day + 2 == 5;
if (answer)
{
return Content("Correct");
}
else
{
return View();
}
}
As you can see, the same action method, “Index,” returns two different types named Content and View; if you want to return multiple types, you have to use the base type as ActionResult.
The above concept also answers the question “When to choose base type ActionResult or derived type?”
Choosing the derived type for a specific result is a good practice, but when you want your action method should return multiple types, then you have to use base type ActionResult.
Now, the important concept comes. There are three categories for the derived types. Let’s take a look at it.
As you can see, there are three categories of data types of ActionResult.
- Content Returning Results
- Redirection Results
- Status Results
Let’s understand each.
Content returning results
As the name depicts these results are used for returning the content to the browser. There are 7 types of content returning results
- ViewResult
- PartialViewResult
- ContentResult
- EmptyResult
- FileResult
- JsonResult
- JavaScriptResult
ViewResult
ViewResult is a datatype that is responsible for returning the View. Let’s look at its example.
public class HomeController : Controller
{
public ViewResult Index()
{
return View();
}
}
The code of the Index view is as follows.
This is Index View.
As you can see in the above code, the index action method is returning the View using the ViewResult type. After this, MVC will find the View having the name “Index” from the “Home” folder in the Views folder. The output is as follows.
The interesting thing with the ViewResult type is you can return a different View regardless of using View having the same name as that of the action method. Look at an example.
public class HomeController : Controller
{
public ViewResult Index()
{
return View(“Second View” );
}
} `
You can see in the figure below that we have a “Second View” page in the views folder.
And the code of the “Second View” page is as follows.
This is Second View but has the action name "Index"
You can see above that MVC will now find the view having the name “Second View” rather than finding the view having the same name as that of the action name. Output is as follows,
Hence, you can call any other view using a different action name with the help of the ViewResult type.
PartialViewResult
It is the type that is used to return the partial view page rather than returning the regular view page. Look at its example.
public class HomeController : Controller
{
public PartialViewResult Index()
{
return PartialView("Second View");
}
}
The code of “Second View” is shown below.
This is Second View but has the action name "Index"
Now the output is different; let’s see below.
As you can see, the output is the same as in the previous example. But the difference is here we can’t see the line “© 2018 - My ASP.NET Application” because it is the line from the Layout page, which is absent here due to the usage of PartialViewResult datatype.
As you can see, the output of PartialViewResult is the same as that of ViewResult. However, the content of the layout page is missing. It is just an example. This is not a real-time example.
Now, let’s look at the example where we’ll see the layout page. Make a new controller named “Student” and an action method named “Name”, as shown below,
public class StudentController : Controller
{
public PartialViewResult Name()
{
return View("_SecondView");
}
}
There is no need to make the View for “Name”. Here, the Name action method calls a different View page. See the folder structure below.
The proper way of creating a partial view page is to be used inside the regular view, having the name start with _, and should reside in the Shared folder.
Now, when you execute it, you will see the same output but have the content of the layout page. See the figure below.
So here, you can use PartialViewResult datatype.
ContentResult
The "Content" result is a datatype that is responsible for the return of content. But the point of interest is you will have proper control over the returned content. I mean to say that you have to add the content in the “Content” helping method of the ContentResult type. Here, you can pass the content like HTML content, Javascript content, or any other content. Let’s understand it with examples.
The code of the Home controller is given below.
public class HomeController : Controller
{
public ContentResult Index()
{
return Content("Zain Ul Hassan");
Its output will be.
You can also give the MIME (Multipurpose Internet Mail Extensions) type in the Content helper method to tell the MVC to take appropriate action after recognizing the content. The code is shown below.
public class HomeController : Controller
{
public ContentResult Index()
{
return Content("Zain Ul Hassan", "text/html");
}
}
Output is the same as above.
You can also give Javascript content, which will be returned by the ContentResult type. Let’s take an example.
public class HomeController : Controller
{
public ContentResult Index()
{
return Content( "" );
}
}
The output will have an alert, as shown below.
So you can use ContentResult datatype in the above way.
EmptyResult
This type is genuinely for returning nothing. But the problem is this EmptyResult type doesn’t have any helper method. So we can use it by making its object, as shown below.
public class HomeController : Controller
{
public EmptyResult Index()
{
return new EmptyResult();
}
}
But if you want to use ActionResult, then MVC will automatically perceive that it is EmptyResult. For code, see below.
public class HomeController : Controller
{
public ActionResult Index()
{
return null;
}
}
So, it is the use of the EmptyResult type.
FileResult
FileResult is a type which is used to return the file to the browser. The helper method for this type is File, which has many overloads. So, if we use the following overload and specify only the URL of the file and the MIME (Multipurpose Internet Mail Extensions) type, then we should see the content of the file in the browser. Let’s take an example.
The overload we use is.
protected internal FilePathResult File(string fileName, string contentType);
The code for the action method using the FileResult type is as follows.
public class HomeController : Controller
{
public FileResult Index()
{
return File("~/Files/text.txt", "text/plain");
}
}
This file is included in the project, and the URL is given above. The output is given below.
Now, if you want to return the file to a byte array, you have to use the following code.
public class HomeController : Controller
{
public FileResult Index()
{
byte[] fileBytes = System.IO.File.ReadAllBytes(Server.MapPath("~/Files/text.txt"));
return File(fileBytes, "text/plain");
}
}
The output is the same as above.
Now, if you don’t want to show the file in the browser and want your file to be asked to download, then you have to use the following overload the file helper method.
protected internal virtual FilePathResult File(string fileName, string contentType, string fileDownloadName);
The code of action using FileResult is given below.
public class HomeController : Controller
{
public FileResult Index()
{
return File(Url.Content("~/Files/text.txt"), "text/plain", "testFile.txt");
}
}
Then, the output will be as shown below.
Hence it is the use of FileResult in different scenarios.
JsonResult
It is the derived type of ActionResult which is used to represent the JSON data. To see how we can JSONify any data, you can see the code below.
public JsonResult Index()
{
return Json(new { Name = "Zain Ul Hassan", ID = 1 });
}
Its output is as follows.
You will get this error after executing the above code. Now, understand what the problem here is.
As you know, JSON contains your encoded data that can be precious, so MVC strictly stops the sharing of information over a GET request. MVC is trying to prevent you from JSON hacking.
So if you want to share the information over the GET request then you have to use the code shown below.
public JsonResult Index()
{
return Json(new { Name = "Zain Ul Hassan", ID = 1 }, JsonRequestBehavior.AllowGet);
}
The output will become.
So, JsonRequestBehavior.AllowGet permits the MVC to share the information over the GET request. But you should use the above feature when you are sure that your JSON data doesn’t contain sensitive data.
JavaScriptResult
This derived type is used to return the JavaScript code from the controller. When it executes, we see the javascript code, as we mentioned in the controller’s action method. For details, let’s take an example.
public JavaScriptResult Index()
{
return JavaScript("alert('Zain Ul hassan')");
}
The output is as shown below.
Redirection results
This type of ActionResult is used for redirection purposes, which you will see with examples here. There are 2 types of redirection results.
- RedirectResult
- Redirect to Action Result
RedirectionResult
If you use this type, then it’ll redirect to the URL you specified. An example is given below.
public RedirectResult Index()
{
return Redirect("https://www.c-sharpcorner.com/members/zain-ul-hassan2");
}
In the output, the specified URL will open, as shown below.
RedirectionResult is better for redirection to live URLs, which means it is not a best practice to use it for redirection to the local pages of the current app. For this purpose, use RedirectionToRouteResult as explained below.
RedirectionToRouteResult
It is responsible for the redirection of the actions within the application. There are many helper methods in it, which are overloads. We use RedirectToRoute, which redirects us to the action within the specified controller. Let’s look at its example.
public RedirectToRouteResult Index()
{
return RedirectToRoute(new { controller = "Student", action = "Name" });
}
We have a Name action method within the Student controller, and the code of the Name view is given below.
Redirection successfull
So, the output is as follows.
Now, if you are in the same controller and don’t want to give the name of the controller, then the better option is the RedirectToAction helper method. Look at the code below,
public class HomeController : Controller
{
public RedirectToRouteResult Index()
{
return RedirectToAction("SecondIndex");
}
public ActionResult SecondIndex()
{
return View();
}
}
The View of SecondIndex’s code is below.
ThisistheSecondIndexofthesamecontrollernamedas"Home"
The output is as follows.
As you can see, the helper method RedirectToAction is used for calling action within the current controller, so if MVC doesn’t find that, a 404 error will occur. RedirectToAction has many overloads; you can give controllers, actions, route values, and much more. So you have to use it according to your scenario.
Status result
Its responsibility is to give the status code to the browser. There are three types of this set explained below.
- HttpStatusCodeResult
- HttpUnauthorizedResult
- HttpNotFoundResult
HttpStatusCodeResult
This type is used to give HTTP status code to the browser. Look at its example.
public HttpStatusCodeResult Index()
{
return new HttpStatusCodeResult(HttpStatusCode.Unauthorized);
}
The output is as shown below.
You can show your message after using the overloaded version of the type HttpStatusCodeResult.
public HttpStatusCodeResult Index()
{
return new HttpStatusCodeResult(HttpStatusCode.Unauthorized, "Sorry! You don't have access.");
}
Output
Here, HttpStatusCode is coming from the System.Net namespace. And it contains all the HTTP status codes.
If you don’t want to use System.Net namespace, then HttpStatusCodeResult has an overload whose output will be the same as above. See the code below.
public HttpStatusCodeResult Index()
{
return new HttpUnauthorizedResult("Sorry! You don't have access.");
}
The output is the same as above, but the code is looking more readable.
HttpNotFoundResult
This is also an overload of HttpStatusCodeResult, but it has the helper method; we don’t have to make an anonymous object. The code is as follows.
public HttpNotFoundResult Index()
{
return HttpNotFound("Sorry! You don't have access.");
}
Output
Summary
These were the basic and foremost things to understand about Action Results. If you have any queries, then feel free to contact me in the comments. Also, giving feedback, either positive or negative, will help me to make my articles better and increase my enthusiasm to share my knowledge.