Action Results And Action Filters In ASP.NET

In ASP.NET MVC, there are different types of action results. We already know that action is actually the term we say to methods of the controller.

Action Result

In ASP.NET MVC, there are different types of action results. We already know that action is actually the term we say to refer to methods of the Controller.

ASP.NET

And there are different types of return statements of actions like View(), JSON(), PartialView() which we use in different scenarios. These helpers are actually the functions of some specific types. And all these types are inherited by ActionResult.

ASP.NET

Yes as we can see we have different return formats of data to return from the action which are all handled by base type ActionResult.

Type (Return Type)Helper MethodDescription
ViewResultView()To return the view from action
PartialViewResultPartialView()It is useful to return partial view.
ContentResultContent()To return simple text
RedirectResultRedirect()To redirect the user to a url
RedirectToRouteResultRedirectToAction()To redirect an action instead of url
JsonResultJson()To return serialize json object
FileResultFile()To return file
HttpNotFoundResultHttpNotFound()To return not found or 404 error
EmptyResult It is used when an action doesn’t need to return any values like void.

So, depending on what an action does, it will return an instance of one of the classes that derive from ActionResult. In our Index action, we’re calling View(), it allows us to  quickly create view results.

Alternatively, we can return the view result like,

return new ViewResult();                   or       return View();

The second approach is more common among ASP.NET MVC developers.

Now, you might ask after watching the above first return statement that if here we’re returning the ViewResult() object then why do we set the return type of the action as ActionResult? So, in this scenario, we’ll simply use the ViewResult action result.

  1. public ViewResult Index() {  
  2.     return View();  
  3. }  

And yes, because it is also a good practice when we need to unit test our action, it will save us from an extra cast in a unit test. But sometimes, it is possible that in an action, we may have different execution paths and return different action results. Then, in such kind of scenarios, we set the return type as,

  1. public ActionResult Index() {  
  2.     return View();  
  3. }  

We can see in the above table that we have many types of action results and only EmptyResult has no action helper because we have nothing to return in that action.

Let’s use some action results in our Controller.

View() Helper

  1. public class StudentsController: Controller   
  2. {   
  3.   // GET: Students      
  4.   public ViewResult Index()      
  5.   {          
  6.     var student = new Student          
  7.     {              
  8.       Name = "Muhammad",              
  9.       DOB = DateTime.Now          
  10.     };          
  11.     return View(student);      
  12.   }  
  13. }  

And we’ve set our View as 

  1. @model SCMS.Models.Student @ {  
  2.     ViewBag.Title = "Index";  
  3. }   
  4. < h2 >  
  5.   @Model.Name   
  6. < /h2>  
  7.     <h3>  
  8.     @Model.DOB  
  9.     </h3 >  

Output
 

ASP.NET

Content() Helper

Now, let’s use the content helper. And see the result.

  1. public ContentResult Index() {  
  2.     return Content("Hello, World!");  
  3. }  

It's all up to us, we can use any approach. But the most preferred approach is to use ActionResult.

ASP.NET

 

HttpNotFound() Helper

  1. public HttpNotFoundResult Index() {  
  2.     return HttpNotFound();  
  3. }  

And here, now, we’ll see the Not Found Error.

ASP.NET

 

One last thing, as we already know that all the action results have same base type ActionResult. But let’s see under the hood practically,

  • I’ve installed Resharper in my Visual Studio. So, it will give us a more accurate result.
  • Right click on HttpNotFoundResult and go to Definition.

    ASP.NET

Now again, right-click on HttpStatusCodeResult and go to Definition.

ASP.NET

 

And finally, we get to the point, so the conclusion is that our custom action results are really derived from the base ActionResult.

Action Filters

Action Filter is nothing but an attribute which we apply before the action. It actually modifies the behavior of an action and an entire controller as well. Here we have several Action Filters in ASP.NET, these filters are executed actually before or after the action execution.

  • Authorization Filter (implements IAuthorizationFilter)
  • Action Filter (implements IActionFilter)
  • Result Filter (implements IResultFilter)
  • Exception Filter (implements IExceptinFilter)

And the order of executing different types of filters are the same as mentioned above.

Action Filter

Here, we have several action filters in asp.net

OutputCache

We use OutputCache attribute to store the output of the action in the cache. If we know that the result of this specific action remains constant and we need to call this action again and again then we need to apply this attribute to the action to make it work fast.

  1. public class StudentController : Controller  
  2. {  
  3.     // GET: Student  
  4.    [OutputCache(Duration = 10)]  
  5. public string Index()  
  6. {  
  7.     return DateTime.Now.ToString("F");  
  8. }  
  9. }  

It actually puts the output into the cache and views it on the screen. Now, if we refresh the screen and request the index action again and again then we’ll see the same time.

Handle Error

It handles the error. If any exception occurs in the action or in the controller, then it shows the “Error” view on the screen instead of throwing the exception.

  1. [HandleError]  
  2. public ActionResult HandleError()  
  3. {  
  4.     throw new NullReferenceException();  
  5. }  

Authorize

We apply this attribute to make it confirm that the user who is requesting this action or this controller is authenticated or not. If we’ve defined the roles in the database then we can customize the authorize attribute by defining the roles here.

  1. [Authorize]  
  2. public class StudentController : Controller  
  3. {  
  4.     // GET: Student  
  5.     [OutputCache(Duration = 10)]  
  6.     public string Index()  
  7.     {  
  8.         return "Huy Candidate";  
  9.     }  
  10.    
  11.     [Authorize(Roles = "Admin")]  
  12.     public ActionResult HandleError()  
  13.     {  
  14.         throw new NullReferenceException();  
  15.     }  
  16. }