Introduction and Background
This article will tell you the basic to advanced foremost concepts about action results in ASP.NET MVC. Last week, one of my friends asked the question “why there is 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
- Redirection Results
- Status Results
The Question
According to the first part of the question, why there is ContentResult
data type in the action method, to understand this, you have to understand about 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 ActionResult
.
Let’s get started with Action Result.
Action Result
Action Result is actually a data type. When it is used with action method, then it is called return type. As you know, an action referred to a method of the controller. So the Action Result is the result of action when it executes. In fact, 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
{
protected ActionResult();
}
}
As you see in Visual Studio, the ActionResult
type is coming from System.Web.Mvc assembly
. And the problem is we can’t see inside this assembly with a feature of Visual Studio “Go to Definition”.
To see inside the assembly, you can either follow the steps given below after downloading ILSpy or you can view my GIF file named as ILSpy.gif after clicking here.
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 after clicking here. - After downloading, Run ILSpy after extracting it.
- Click on File (on top-left-corner).
- Select “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 also. - The types of
ActionResult
are shown in the image below:
Now you can see, the ActionResult
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
{
protected ActionResult();
}
}
It is an abstract
class because actions of a controller can return different types of data at the same time. So it has to be abstract
so that every Http request could handle 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, same action method “Index
” returning two different types named Content
and View
. So if you want to return multiple types, you have to use base type as ActionResult
.
The above concept also answers the question “When to choose base type ActionResult
or derived type?”
The answer is, choosing a derived type for a specific result is a good practice, but when you want that, 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 that, 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
which is responsible for returning the View
. Let’s look at its example.
public class HomeController : Controller
{
public ViewResult Index()
{
return View();
}
}
And the code of Index view is as follows:
<h2> This is Index View. </h2>
As you can see the above code, index action method is returning the View using ViewResult
type. After this, MVC will find the View having name “Index
” from the “Home” folder in the Views folder.
Output
The interesting thing with 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 “Second View” page in views folder:
And the code of “Second View” page is as follows:
<h2>This is Second View but having action name "Index"</h2>
You can see above, now MVC will find the view having name “Second View” rather than finding the view having the same name as the action name.
Output
Hence, you can call any other view using different action name with the help of ViewResult
type.
PartialViewResult
It is the type which 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");
}
}
And the code of “Second View” is shown below:
<h2>This is Second View but having action name "Index"</h2>
Output
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 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
. But the content of layout page is missing. It is just an example. This is not the real-time example.
Now let’s look at an example where we’ll see layout page. Make a new controller named as “Student
” and an action method named as “Name
”, as shown below:
public class StudentController : Controller
{
public PartialViewResult Name()
{
return View("_SecondView");
}
}
There is no need to make the View
for “Name
”. Because here, the Name
action method is calling a different View
page. See the folder structure below:
The proper way of creating partial view page is, it should 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 content of layout page. See figure below:
So here, you can use PartialViewResult
datatype
.
ContentResult
The ContentRresult
is a datatype
which is responsible for the returning 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 ContentResult
type. Here, you can pass the contents like HTML content, JavaScript content or any other content. Let’s understand it with examples.
Code of Home controller is given below:
public class HomeController : Controller
{
public ContentResult Index()
{
return Content("<h3>Zain Ul Hassan </h3>");
}
}
Output
You can also give 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 as shown below:
public class HomeController : Controller
{
public ContentResult Index()
{
return Content("<h3>Zain Ul Hassan</h3>", "text/html");
}
}
The output is the same as above:
You can also give JavaScript content which will return by ContentResult
type. Let’s take an example.
public class HomeController : Controller
{
public ContentResult Index()
{
return Content(
"<script> alert('Hi! I am Zain Ul Hassan') </script>"
);
}
}
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 you want to use ActionResult
, then MVC will automatically perceive that it is of EmptyResult
. For code, see below:
public class HomeController : Controller
{
public ActionResult Index()
{
return null;
}
}
So, it is the use of 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
, and 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);
And the code for action method using 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. And the output is given below:
Now if you want to return the file in byte array then you have to use 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 same as above:
Now if you don’t want to show the file in the browser and want that your file should 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");
}
}
Output
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 can we JSONify any data, you can see 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. In fact, MVC is trying to prevent you from JSON Hijacking.
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 for returning 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')");
}
And the View
named as Index
has the following code:
<script type="text/javascript" src="@Url.Action("Index")"></script>
The output is as shown below:
Redirection Results
This type of ActionResult
is used for redirection purpose, 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 specified by you. 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 mean to say 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 to the actions within the application. There are many helper methods in it which are actually overloaded. We use RedirectToRoute
which redirect 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 Name
action method within the Student
controller, and the code of Name
view is given below:
<h2>Redirection Successfull</h2>
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 of is, RedirectToAction
helper method. Look at the code below:
public class HomeController : Controller
{
public RedirectToRouteResult Index()
{
return RedirectToAction("SecondIndex");
}
public ActionResult SecondIndex()
{
return View();
}
}
And the View of SecondIndex
’s code is below:
<h3>This is the SecondIndex of the same controller named as "Home"</h3>
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, 404 error will occur. RedirectToAction
has many overloads, you can give controllers, actions, route values and much more. So you have to use 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 own 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 System.Net
namespace. And contains all the HTTP status codes.
If you don’t want to use System.Net
namespace, then HttpStatusCodeResult
has such 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 looks 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 below. Also, give feedback, either positive or negative - it will help me to make my articles better and increase my enthusiasm to share my knowledge.