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!
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.