Business has evolved. What about your technology solutions?
Get a Quote
EN
 
 
Binary Studio
Binary is valuable ideas for your business

HomeBlogTechnical

ASP.NET MVC Custom Action Filters

This article explains how to create custom filter attribute in ASP.NET MVC. General purpose of the action and result filters are .NET attributes, derived from FilterAttibute, that also implements IActionFilter or IResultFilter, or both. Also there are some good examples of creating log filters, which are also quite demanded in ASP.NET MVC software development.

So, this article I’d like to tell you about creating your custom filter attribute in ASP.NET MVC (If you're looking for asp.net mvc development services, check our services page). General purpose action and result filters are .NET attributes, derived from FilterAttibute, that also implement IActionFilter or IResultFilter, or both. It’s easier to derive a subclass of the built-in ActionFilterAttibute (it is implemented in both interfaces). There are four methods you can implement:

ASP.NET MVC Methods

Method When called Special things
OnActionExecuting() Before the action runs You can prevent execution of the action method by assigning an ActionResult to filterContext.Result. You can inspect and edit filterContext. ActionParameters, the parameters that will be used when calling the action method.
OnActionExecuted() After the action runs You can obtain details of any exception thrown by the action method from filterContext.Exception, and optionally mark it as “handled” by setting filterContext.ExceptionHandled = true. You can inspect or change the ActionResult using filterContext.Result.
OnResultExecuting() Before the ActionResult is executed You can inspect (but not change) the ActionResult using filterContext.Result. You can prevent its execution by setting filterContext.Cancel=true.
OnResultExecuted() After the ActionResult is executed You can obtain details of any exception thrown by the ActionResult from filterContext.Exception, and optionally mark it as “handled” by setting filterContext.ExceptionHandled=true. You can inspect (but not change) the ActionResult using filterContext.Result.

ASP.NET MVC Filter Sample

So simple filter looks like:

public class ShowMessageAttibute : ActionFilterAttribute
{
public string Message { get; set; }

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.HttpContext.Response.Write("Before action:" + Message);
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
filterContext.HttpContext.Response.Write("After action:" + Message);
}

public override void OnResultExecuting(ResultExecutingContext filterContext)
{
filterContext.HttpContext.Response.Write("Before result:" + Message);
}

public override void OnResultExecuted(ResultExecutedContext filterContext)
{
filterContext.HttpContext.Response.Write("After result:" + Message);
}
}

And you can use it as:

[ShowMessageAttibute(Message = "Hello world!")]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";

return View();
}
}

As a result you’ll see all messages which we added in filter. It was really easy, isn’t it?

Now I’ll create more useful filter. This filter will save all site's activity for action method, IP, action and controller names and exception if it’ll be (I’ll use log4net lib for it but you can use any other technology for it ADO.NET Entity Framework, NHibernate, etc).

So first of all I created ASP.NET MVC Web Application in MS VS 2009. After this I added LogsRequestsAttribute.cs and added following code:

public class LogsRequestsAttribute : ActionFilterAttribute, IActionFilter
{
private static ILog log = LogManager.GetLogger(typeof(LogsRequestsAttribute));

void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
{
ThreadPool.QueueUserWorkItem(delegate
{
try
{
string message =
string.Format(
"Action= \"{0}\", Controller= \"{1}\", IPAddress= \"{2}\"" +
"TimeStamp= \"{3}\"",
filterContext.RouteData.Values["action"] as string,
filterContext.Controller.ToString(),
filterContext.HttpContext.Request.UserHostAddress,
filterContext.HttpContext.Timestamp);

log.Info(message);
}
finally
{
}
});
}

void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Exception != null)
{
ThreadPool.QueueUserWorkItem(delegate
{
try
{
string message = filterContext.Exception.Message;
log.Info(message);
}
finally
{
}
});
}
}
}

I don’t explain how you should add and configurate log4net in your app because it’s very simp-ly and it isn’t a goal of this article). In code I used ThreadPool object because user don’t have to wait for logging. So that’s all! Now we can use this filter in our controller or in any action:

 [HandleError] 
[LogsRequestsAttribute]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";

return View();
}

public ActionResult About()
{
throw new Exception("Error!");

return View();
}

If you add filter to controller, it’ll be called for all action in it). I specially throw axception in AboutAction to check this filter for exception. As a result in log file we can see:

Logging successfully initialized

Action= "Index", Controller= "MvcLogApp.Controllers.HomeController", IPAddress= "127.0.0.1"TimeStamp= "15.09.2009 15:56:01"

Action= "About", Controller= "MvcLogApp.Controllers.HomeController", IPAddress= "127.0.0.1"TimeStamp= "15.09.2009 15:56:06"

Error!

So as we see it works and it really simple. (BTW: you can add information in ViewData object in filter and use it on view). You can download code here.

Hope it’ll help somebody!

 

Artyom G, .NET team,
Binary Studio

Leave a comment

 

We are more than happy to hear from you

Privacy policy Binary Studio will not sell or rent your information to any 3rd party vendors.
Read our privacy policy.

Subscribe to our newsletter

 

Recent Comments

Archives

Meta

 
  • Testimonials

  • Showcase

    Showcase
  • Blog

    Blog
 
 
Home page      About Us      Services      Case Studies      Blog      Prices      Contact us      Sitemap      Our Prices
Email: info@binary-studio.com    Tel: +380.62.206.84.61 Copyright 2005-2012 Binary Studio
Social