Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# dotnet core 2 pass data from middleware/filter to controller method

currently we are writing a web application with dotnet core 2.

We actually create some kind of multi-hosting platform where we can register new clients based on the url passed to our application.

However currently we wanted to create a middleware/filter to validate our client's.

Actually what we wanted to do is pull an object from the database and check if it exists, if yes, we want to call the controller method and make the object accessible, if it does not exist, we actually want to abort and show an error page.

What we already have done is created a filter/middleware that does exactly that, however we couldn't figure out a way to access the object that we already pulled in our filter/middleware inside the controller method.

is there actually any documentation for doing that?

I actually tried to figure it out from: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware?tabs=aspnetcore2x https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters

but they don't describe a way to do it, only to actually do something before/after the action.

like image 278
Christian Schmitt Avatar asked Oct 06 '17 08:10

Christian Schmitt


2 Answers

You could add the object to the context using HttpContext.Items which the docs state:

The Items collection is a good location to store data that is needed only while processing one particular request. The collection's contents are discarded after each request. The Items collection is best used as a way for components or middleware to communicate when they operate at different points in time during a request and have no direct way to pass parameters.

For example, in your middleware:

public class MySuperAmazingMiddleware
{
    private readonly RequestDelegate _next;

    public MySuperAmazingMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public Task Invoke(HttpContext context)
    {
        var mySuperAmazingObject = GetSuperAmazingObject();

        context.Items.Add("SuperAmazingObject", mySuperAmazingObject );

        // Call the next delegate/middleware in the pipeline
        return this._next(context);
    }
}

Then later on in your action method, you can read the value:

var mySuperAmazingObject = (SuperAmazingObject)HttpContext.Items["mySuperAmazingObject"];
like image 157
DavidG Avatar answered Oct 08 '22 10:10

DavidG


One way of doing it (not saying it's the only or the best) is to have DI inject a proxy of the object, you set the real value of the object in your middleware, then you can access it from the proxy in the controller.

Note: if you'll pass the proxy object in the method call instead of controller, don't forget to mark it with [FromServices] attribute.

Another way would be adding the object to the request Items property. but when you read it you'll need casting from object to your actual class.

like image 44
T.Aoukar Avatar answered Oct 08 '22 10:10

T.Aoukar