FluentFilters for ASP.NET MVC 3 - Register global filters by specified conditions
- Download binary - 445 KB
- Download source - 1.21 MB
- Latest version can be found at fluentfilters.codeplex.com

Introduction
Last year I wrote about FluentFilters and how to use them with ASP.NET MVC 2 to implement the functionality of global filters. With ASP.NET MVC 3 was added native support for global filters. You can register a global filter by using the GlobalFilters.Filters static registration endpoint. It works great, but sometimes it would be nice to specify conditions for running the filter like criteria in FluentFlters.
Recently, I updated the library and added a version for ASP.NET MVC 3 in which I implemented the functionality described above. This version was completely rewritten in accordance with the new features of ASP.NET MVC 3. As a result of this, the library became smaller and easier to use.
Please note that the versions for ASP.NET MVC 2 and ASP.NET MVC 3 are different. The assembly for ASP.NET MVC 2 is now located in the /bin/mvc2 folder of the library binary package (to learn how to use it, please read the previous article).
Below, I describe the FluentFilters for ASP.NET MVC 3:
- How to configure the application to work with the library
- How to register filters and specify conditions by criteria
- How to create custom criteria
Let's start
To start using FluentFilters is very simple:
- Download the latest version of the library from the Downloads page at CodePlex.
- Unzip the zip file and add a reference to /bin/mvc3/FluentFilters.dll in your MVC project.
- Instead of steps 1-2, you can use NuGet. Right click on References and click Add Library Package Reference. Click Online on the left side, and in the Search box at the upper right, type in "FluentFilters". Click Install. Alternatively, open the Package Manager Console and type "Install-Package FluentFilters".
- Register the
FluentFiltersCollectionfilter provider in Global.asax.cs. - Use the
FluentFiltersBuider.Filtersstatic registration endpoint to register a global filter with conditions.
It should look like below:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
// Register provider
FilterProviders.Providers.Add(FluentFiltersBuider.Filters);
// Register Global Filters
RegisterGlobalFilters(GlobalFilters.Filters,
FluentFiltersBuider.Filters);
RegisterRoutes(RouteTable.Routes);
}
public static void RegisterGlobalFilters(GlobalFilterCollection filters,
FluentFilterCollection fluentFilters)
{
filters.Add(new HandleErrorAttribute());
fluentFilters.Add<DisplayTopBannerFilterAttribute>(c => {
c.Require(new AreaFilterCriteria("Blog")).Or(new AreaFilterCriteria("Forum"));
c.Exclude(new ControllerFilterCriteria("Admin")).And(
new AreaFilterCriteria("Forum"));
});
}
Registering filters
To register a filter, you need to call the method FluentFilterCollection.Add(). The provider has a few method definitions:
// Register filter by type
void Add<T>()
void Add<T>(int order)
void Add<T>(Action<IFilterCriteriaBuilder> criteria)
void Add<T>(Action<IFilterCriteriaBuilder> criteria, int order)
// Register filter by instance
void Add(object filter, Action<IFilterCriteriaBuilder> criteria)
void Add(object filter, Action<IFilterCriteriaBuilder> criteria, int order)
By using registration, for instance, you can set values for the properties:
fluentFilters.Add( new HandleErrorAttribute() { View = "ErrorPage" },
c => { c.Require(new AreaFilterCriteria("Admin"))} );
Specify conditions
To specify the conditions, you should set the chain of criteria for the filter at registration. Using criteria, you can set whether to execute a filter or not. The library already provides three criteria for use:
ActionFilterCriteria- filter by specified actionAreaFilterCriteria- filter by specified areaControllerFilterCriteria- filter by specified controller
For one filter, you can only specify two chains of criteria. These are the chains of criteria that are required and which should be excluded.
fluentFilters.Add<CheckAuthenticationAttribute>(c =>
{
// Execute if current area "Blog"
c.Require(new AreaFilterCriteria("Blog"));
// But ignore if current controller "Account"
c.Exclude(new ControllerFilterCriteria("Account"));
});
Chains of criteria are constructed by using the methods And(IFilterCriteria criteria) and Or(IFilterCriteria criteria), which work as conditional logical operators && and ||.
fluentFilters.Add<DisplayTopBannerFilterAttribute>(c =>
{
c.Require(new IsFreeAccountFilterCriteria()).Or(
new AreaFilterCriteria("Blog")).Or(
new AreaFilterCriteria("Forum")).And(
new IsMemberFilterCriteria());
c.Exclude(new AreaFilterCriteria("Administrator")).Or(
new ControllerFilterCriteria("Account")).And(
new ActionFilterCriteria("LogOn"));
});
If using the C# language, then the code above can be understood as (like pseudocode):
if( IsFreeAccountFilterCriteria() || area == "Blog" ||
(area == "Forum" && IsMemberFilterCriteria()) )
{
if(area != "Administrator")
{
DisplayTopBannerFilter();
}
else if(controller != "Account" && action != "LogOn")
{
DisplayTopBannerFilter();
}
}
Creating a custom criteria
To create a custom criteria, you should inherit your class from the FluentFilters.IFilterCriteria interface and implement only one method Match. For example, see the source code for ActionFilterCriteria:
public class ActionFilterCriteria : IFilterCriteria
{
#region Fields
private readonly string _actionName;
#endregion
#region Constructor
/// <summary>
/// Filter by specified action
/// </summary>
/// <param name="actionName">Name of the action</param>
public ActionFilterCriteria(string actionName)
{
_actionName = actionName;
}
#endregion
#region Implementation of IActionFilterCriteria
public bool Match(ControllerContext controllerContext,
ActionDescriptor actionDescriptor)
{
return string.Equals(_actionName,
controllerContext.RouteData.GetRequiredString("action"),
StringComparison.OrdinalIgnoreCase);
}
#endregion
}
发表评论
pqJVM9 Major thankies for the article.Much thanks again. Will read on
4amkP2 sure, study is having to pay off. So pleased to have located this post.. So content to have located this post.. So content to get located this article..
I2djeO Im thankful for the article post.Much thanks again. Awesome.
i18QA1 Major thankies for the blog.Really thank you! Awesome.
tRDIRV This site is mostly a stroll-by means of for all the data you needed about this and didn't know who to ask. Glimpse here, and also you'll definitely uncover it.
jSYwil Wow, fantastic weblog format! How long have you ever been blogging for? you made blogging look easy. The total glance of your web site is magnificent, let alone the content!
J792Fw There is noticeably a bundle to identify about this. I think you made some good points in features also.
ikOgXQ I don't even know how I ended up here, but I thought this post was great. I do not know who you are but definitely you are going to a famous blogger if you aren't already ;) Cheers!
sAThKa A round of applause for your blog.Really thank you! Will read on...
THR7ul Im obliged for the blog post. Really Cool.
QMoe12 I really enjoy the blog post.Much thanks again. Fantastic.
3JYPL5 Awesome article.Really looking forward to read more. Really Great.
R4pmW8 Very informative blog.Thanks Again. Cool.
8ok9t2 Im thankful for the article post. Awesome.
Oz60PB Appreciate you sharing, great post.Really thank you! Cool.
A3R1Io Thank you ever so for you article post.Really looking forward to read more. Much obliged.
Kt6REO I think this is a real great post.Much thanks again. Cool.
KogwxX I truly appreciate this article.Really thank you! Will read on...
349H2E Im obliged for the article post. Awesome.
XZCcj8 Thanks a lot for the blog article.Really looking forward to read more. Cool.
wDCEWk Im obliged for the post.Really thank you! Awesome.
vwPsLh Say, you got a nice blog post.Really looking forward to read more. Want more.
B6JeTh I cannot thank you enough for the blog. Keep writing.
Hey, I enjoy your internet site if I'm honest. Wherever did you get it built?