Click here to Skip to main content
14,211,427 members
Click here to Skip to main content

Stats

32.9K views
5 bookmarked

Understand Run, Use, Map and MapWhen to Hook Middleware in HTTP Pipeline of ASP.NET5

,
Rate this:
4.61 (10 votes)
Please Sign up or sign in to vote.
4.61 (10 votes)
6 Jan 2016     CPOL    
Understand Run, Use, Map and MapWhen to hook middleware in HTTP pipeline of ASP.NET5

Introduction

It’s more transparent to hook middleware in ASP.NET 5 application compared to prior versions. We can use Run, Map and Use extension method to hook any middleware in between HTTP pipeline. In this example, we will understand the difference among them with an example.

Run Extension

The nature of Run extension is to short circuit the HTTP pipeline immediately. It is a shorthand way of adding middleware to the pipeline that does not call any other middleware which is next to it and immediately return HTTP response. So, it’s recommended to use Run extension to hook middleware at last in HTTP pipeline. Let’s see how Run behaves in action.

public void Configure(IApplicationBuilder app)
    {
        app.UseMvc();
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Return From Run.");
        });
        app.Run(async context => {
            await context.Response.WriteAsync("This is second Run.");
        });
    }

Here, we hook two Run functions next to next and while running, we are getting only response from first Run.

That implies the first run has short circuit the HTTP request and sends response from itself without forwarding to next middleware.

Use Extension

In case of Use extension, there is a chance to pass next invoker, so that HTTP request will be transferred to the next middleware after execution of current Use if there next invoker is present. In this example, we have attached next invoker with Use extension, so that HTTP call will get transferred to next middleware even we tried to return:

public void Configure(IApplicationBuilder app)
    {
        app.UseMvc();
        app.Use(next=> async context =>
        {
            await context.Response.WriteAsync("Return From Use.");
            await next.Invoke(context);
        });
        app.Run(async context => {
            await context.Response.WriteAsync("This is from Run.");
        });
    }

HTTP response within Use extension. Here is the output of the above code fragment.

We are seeing that both strings from Use and Run have printed as output. Here, we should notice that we are forwarding the HTTP request to next level by adding the following line.

await next.Invoke(context);

Otherwise, Use extension will not escalate HTTP request and will behave as Run Extension method.

app.Use(next=> async context =>
   {
       await context.Response.WriteAsync("Return From Use.");
   });

Once we remove the next.Invoker(), we are getting output only from Use Extension.

Map Extension

Map extensions are used as convention for branching the pipeline. We can hook delegate to Map extension to push it to HTTP pipeline. Map simply accepts a path and a function that configures a separate middleware pipeline. In this example, we will hook one middleware/delegate to HTTP pipeline using Map extension.

private static void MyDelegate(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Returning from Map");
        });
    }
    public void Configure(IApplicationBuilder app)
    {
        app.UseMvc();
        app.Map("/MyDelegate", MyDelegate);
    }

In Map extension, we have hooked MyDelegate delegate with “/MyDelegate” path. So, when user will perform any HTTP call to the same path, the delegate function will get triggered.

The message has returned from delegate function. One fact we should notice that, Map takes delegate and within delegate, it allows to use both Run and Use depending on the requirement. MapWhen Extension supports path-based mapping, the MapWhen method supports predicate-based middleware branching, allowing separate pipeline to be constructed in a flexible way. In this example, we have mapped middleware execution with the presence of query string “q” in URL.

private static void HandleQuery(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Return from HandleQuery");
        });
    }
    public void Configure(IApplicationBuilder app)
    {
        app.UseMvc();
        //Execute when "q" is there in query string
        app.MapWhen(context => {
            return context.Request.Query.ContainsKey("q");
        }, HandleQuery);
        //Return response for other request
        app.Run(async context =>
        {
            await context.Response.WriteAsync("From Run extension");
        });
    }

This type of branching is very useful when we have a separate handler to handle a certain request. For example, in some scenarios, we may want to bypass AJAX call to some handler like this:

private void HandleAJAX(IApplicationBuilder app)
{
}
public void Configure(IApplicationBuilder app)
{
    app.UseMvc();
    app.MapWhen(ctx =>
ctx.Request.Headers.Get("X-Requested-With") == "XMLHttpRequest", HandleAJAX);
}

Here, we are checking for “X-Request-With” header in the current HTTP request. If the header is present, then the request is AJAX request and for that HandleAJAX handler will take care of.

Summary

Middleware are a well known feature in ASP.NET which was incepted in form of HTTP Handler and HTTP module in the early Web Forms days followed by Delegating handler and Middleware (MVC6) in MVC framework. In this tip, we have learned to use Run, Use, Map and MapWhen extension method to hook middleware in ASP.NET 5/MVC6 HTTP pipeline. Those methods are ready to accept custom middleware too. Developers can easily create their own middleware to inject additional functionality in HTTP pipeline.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Sourav Kayal
Software Developer DELL International
India India
I am software developer from INDIA. Beside my day to day development work, i like to learn new technologies to update myself. I am passionate blogger and author in various technical community including dotnetfunda.com , c-sharpcorner.com and codeproject. My area of interest is modern web technology in Microsoft stack. Visit to my personal blog here.

http://ctrlcvprogrammer.blogspot.in/

Comments and Discussions

 
QuestionPlease fix images of responses Pin
Michael Freidgeim29-Nov-17 10:42
memberMichael Freidgeim29-Nov-17 10:42 
GeneralMy vote of 5 Pin
Santhakumar M7-Jan-16 0:43
professionalSanthakumar M7-Jan-16 0:43 
GeneralMy vote of 5 Pin
Camilo Reyes6-Jan-16 12:02
professionalCamilo Reyes6-Jan-16 12:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Layout: fixed | fluid

Article Copyright 2016 by Sourav Kayal
Everything else Copyright © CodeProject, 1999-2019

Server Web01
Version 2.8.190619.1