Search code examples
c#asp.net-coremiddleware

ASP.NET Core - Add Custom Property to HttpRequest


I have some ASP.NET Middleware that analyzes a request as it comes in. Based on what's available in that HttpRequest, I would like to add a custom property that I can use in my code. My question is, is there a way for me to add a property to HttpRequest so that I can access it in my controller? For example, in my Controller, I would like to do something like this:

namespace MyWebsite.Controllers
{
  public class MyController : Controller

  public IActionResult Index()
  {
    if (this.Request.MyProperty == null)
    {
      return View("~/Views/NoExist.cshtml");
    }
    return View ("/Views/Index.cshtml");
  }
}

MyProperty represents the custom property that I would like to inject, or add, via my custom middleware. Is this possible? If so, how? If not, what is the recommended approach?

Thank you!


Solution

  • The traditional way of achieving what you want is sharing everything via HttpContext.Items. That way you should manage the keys yourself or even can declare your extension methods for conveniently setting & getting the values.

    However here I'd like to introduce a new way associated with a new concept request feature in asp.net core. The features associated with each request can be added by different middlewares along the pipeline and can be consumed by any (if available). That looks like neater and more organized, although may not be very convenient compared to the old way.

    Suppose you're in the context of your middleware, the following code will add a feature which exposes your property:

    //declare the feature interface first
    public interface IMyFeature {
        string MyProperty {get;}
    }
    
    //the concrete type for the feature
    public class MyFeature : IMyFeature {
        public MyFeature(string myProperty){
            MyProperty = myProperty;
        }
        public string MyProperty {get;}
    }
    
    //the context is in your middleware
    //add the feature
    var myFeature = new MyFeature("value of your choice");
    //context here is the HttpContext
    context.Features.Set<IMyFeature>(myFeature);
    

    Now anywhere later in the pipeline, you can consume the feature added like this:

    //context here is the HttpContext
    var myFeature = context.Features.Get<IMyFeature>();
    if(myFeature != null){
        //consume your feature
    }
    

    One point I think the request features concept is good about is its clear definition of feature interfaces which can be learned, referenced and managed easily by your code. Even porting it to some library for reusing makes more sense than depending on some constant key for accessing the shared data (as achieved by using HttpContext.Items). Of course for some simple data sharing, you can just use HttpContext.Items, the request feature should be used when it may evolve later, has a clear cool concept around it and may contain more data.