Plug ASP.NET Core Middlware in MVC Filters Pipeline

Oct 27, 2016     Viewed 1216 times    2 Comments
Posted in #Middleware  #MVC Filters 

As we know that any ASP.NET Core built on top of a middleware pipeline, each middleware handles and perform a specific task or functionality such as Authentication, Authorization, Routing, Localization .. etc. Simillarly MVC has it's own filter pipeline, where each filter type is executed at a different stage in the pipeline.

There are some scenraios where you want to apply middleware to only a specific controller or action, unfortunelty there no built in feature allow us to do that previously, but after MiddlwareFilterAttribute introduced you are able to achieve that easily.

I remembered long time back that I wrote an article about Localization & Routing in ASP.NET Core 1.0 frankly I faced a crucial issue. The httpContext.GetrouteData() always returns null, because the routings are not built yet, only after the calling UseMvc(). But registering the localization after this point is already to late to determine the locale.

Let's see how we can acheive this using the new MiddlwareFilterAttribute.

To use middleware as a filter you first create a type with a Configure method that specifies the middleware pipeline that you want to use (in our case localization):

public class LocalizationPipeline {

    public void Configure(IApplicationBuilder app) {
    
        var supportedCultures = new[]
        {
            new CultureInfo("en-US"),
            new CultureInfo("fr")
        };

        var options = new RequestLocalizationOptions() {
         
            DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US"),
            SupportedCultures = supportedCultures,
            SupportedUICultures = supportedCultures
        };

        options.RequestCultureProviders = new[] { new RouteDataRequestCultureProvider() { Options = options } };

        app.UseRequestLocalization(options);
    }
}

Then you apply that middleware pipeline to a controller, an action or globally using the MiddlewareFilterAttribute:

[Route("{culture}/[controller]/[action]")]
[MiddlewareFilter(typeof(LocalizationPipeline))]
public IActionResult CultureFromRouteData() {

  return Content($"CurrentCulture:{CultureInfo.CurrentCulture.Name},CurrentUICulture:{CultureInfo.CurrentUICulture.Name}");

}

That is it!! there are a lot of things that you can do using this rich composition other than localization using route data, for example you could apply response compression or caching to a specific action .. etc.

Twitter Facebook Google + LinkedIn


2 Comments

Os1r1s110 (11/5/2016 12:57:25 PM)

Hi Hisham, nice article there! I would have a little question regarding the RouteDataRequestCultureProvider, how can we apply it globally without having to specify it in front of every controller? Is it possible?

I tried figuring out how to put it in the configure pipeline but the other localization providers need to be put before the addMvc and this one needs to be done after to have access to URL segments (as of my understanding, it's not totally clear yet in my mind), would you have an advise?

thanks in advance!

Hisham Bin Ateya (11/6/2016 8:31:21 AM)

@Os1r1s110 can you checkout the sample here. Regarding the global route you can define the culture segments in the route template, please refere to the example here


Leave a Comment