Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Define a variable in a middleware available to the following ones

I am using asp.net core, and I would like to get several data from the request before I call the full web app.

So I created a middleware to do this. I found a way to check everything I want, but I don't know how to pass a variable to the following middlewares

app.Use(async (context, next) => {
    var requestInfo = GetRequestInfo(context.Request);
    if(requestInfo == null)
    {
        context.Response.StatusCode = 404;
        return;
    }

    // How do I make the request info available to the following middlewares ?

    await next();
});

app.Run(async (context) =>
{
    // var requestInfo =  ???
    await context.Response.WriteAsync("Hello World! - " + env.EnvironmentName);
});

Is there a good way to pass data from a middleware to others ? (here I use app.Run, but I would like to have all this in MVC)

like image 760
glacasa Avatar asked Nov 15 '16 15:11

glacasa


People also ask

What is a middleware in C#?

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.

What is difference between filter and middleware?

Middlewares run on every request, regardless of which controller or action is called. Filters have full access to the MVC context , meaning that we have access to the: routing data, current controller, ModelState, etc. For example, we could create a filter that validates the input model.

How do I put middleware in net core?

Search for word "middleware" in the top right search box as shown below. Select Middleware Class item and give it a name and click on Add button. This will add a new class for the middleware with extension method as shown below.


2 Answers

Beside features, there is another - a simpler in my opinion - solution: HttpContext.Items, as described here. According to the docs, it is especially designed to store data for the scope of a single request.

Your implementation would look like this:

// Set data:
context.Items["RequestInfo"] = requestInfo;

// Read data:
var requestInfo = (RequestInfo)context.Items["RequestInfo"];
like image 167
Henk Mollema Avatar answered Sep 28 '22 04:09

Henk Mollema


I found the solution : the context contains an IFeatureCollection, and it is documented here

We just need to create a class with all the data :

public class RequestInfo
{
    public String Info1 { get; set; }
    public int Info2 { get; set; }
}

And we add it to the context.Features :

app.Use(async (context, next) => {
    RequestInfo requestInfo = GetRequestInfo(context.Request);
    if(requestInfo == null)
    {
        context.Response.StatusCode = 404;
        return;
    }

    // We add it to the Features collection
    context.Features.Set(requestInfo)

    await next();
});

Now it is available to the others middlewares :

app.Run(async (context) =>
{
    var requestInfo = context.Features.Get<RequestInfo>();
});
like image 20
glacasa Avatar answered Sep 28 '22 04:09

glacasa