Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asp.Net Core 2.x middleware syntax

I encountered several ways of writing simple middleware directly in Startup.Configure() method:

// Syntax 1.
app.Use((context, next) =>
{
    context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
    return next();
});

// Syntax 2.
app.Use(async (context, next) =>
{
    context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
    await next();
});

// Syntax 3.
app.Use(async (context, next) =>
{
    context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
    await next.Invoke();
});

// Syntax 4.
app.Use(next =>
{
    return ctx =>
    {
        ctx.Response.Headers.Add("X-Content-Type-Options", "nosniff");
        return next(ctx);
    };
});

Are they all the same?

like image 214
synergetic Avatar asked Jun 20 '18 01:06

synergetic


People also ask

How do you define middleware in .NET Core?

A middleware is nothing but a component (class) which is executed on every request in ASP.NET Core application. In the classic ASP.NET, HttpHandlers and HttpModules were part of request pipeline. Middleware is similar to HttpHandlers and HttpModules where both needs to be configured and executed in each request.

What is middleware in ASP.NET Core with example?

Middleware is software that's assembled into an app pipeline to handle requests and responses. Each component: Chooses whether to pass the request to the next component in the pipeline. Can perform work before and after the next component in the pipeline.

How do I add middleware to the application request pipeline?

Now, we need to add our custom middleware in the request pipeline by using Use extension method as shown below. We can add middleware using app. UseMiddleware<MyMiddleware>() method of IApplicationBuilder also. Thus, we can add custom middleware in the ASP.NET Core application.

How do I redirect in middleware NET Core?

In a browser with developer tools enabled, make a request to the sample app with the path /redirect-rule/1234/5678 . The regular expression matches the request path on redirect-rule/(. *) , and the path is replaced with /redirected/1234/5678 . The redirect URL is sent back to the client with a 302 - Found status code.


2 Answers

Syntax 1 and Syntax 2 are functionally different. Syntax 1 does not wait for next() to finish its Task. Syntax 1 is passing a normal lambda function to Use and is returning the Task without waiting for it to complete. Syntax 2 is passing an async lambda function and is awaiting the Task before returning. The await keyword tells the app to pause execution until the next() task is complete. In the code from your example, that might not lead to a functional difference, but there are times when waiting for a Task to complete can make a difference.

Syntax 2 and Syntax 3 are syntactically different and functionally identical. Syntax 2 is just a user-friendly versions of Syntax 3. See Func<T>() vs Func<T>.Invoke()

Syntax 1 and Syntax 4 are syntactically different and functionally identical. Syntax 1 is just a user-friendly wrapper around Syntax 4. See UseExtension.cs

// syntax 1,2,3 use this 
public static IApplicationBuilder Use(
    this IApplicationBuilder app, 
    Func<HttpContext, Func<Task>, Task> middleware)
{
    // which calls into syntax4
    return app.Use(next =>
    {
        return context =>
        {
            Func<Task> simpleNext = () => next(context);
            return middleware(context, simpleNext);
        };
    });
}
like image 74
Shaun Luttin Avatar answered Nov 07 '22 20:11

Shaun Luttin


Syntax 4 is using Use method of IApplicationBuilder

IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)

Syntax 1, 2 and 3 are using an extension method for IApplicationBuilder which is a wrapper of previous method in Syntax 4. Here's the implimentation

public static IApplicationBuilder Use(this IApplicationBuilder app, Func<HttpContext, Func<Task>, Task> middleware)
{
    return app.Use(next =>
    {
        return context =>
        {
            Func<Task> simpleNext = () => next(context);
            return middleware(context, simpleNext);
        };
    });
}

For Syntax 2 and 3, there is no difference between next.Invoke() and next(). They both compile to the same method.

like image 43
Kahbazi Avatar answered Nov 07 '22 19:11

Kahbazi