Reputation: 1501
Trying to add special endpoints to an ASP.NET Core MVC through a middleware.
In a app.UseWhen
, I need to parse the request URL. In a Controller context, MVC does a great job extracting userId
using the following template:
GET http://contoso.com/users/{userId}/addresses
How could this be cleanly done in a middleware where MVC Controller constructs aren't setup?
Bonus points if the answer helps figuring out if the address conforms to this pattern in the first place.
All I have on hand is a DefaultHttpContext.
Upvotes: 3
Views: 8860
Reputation: 1501
Solution based on Mark Vincze's blog
This method used to extract the the user id and work with it...
private static void AddAddressesRoute(IApplicationBuilder app, RouteBuilder builder)
{
builder.MapVerb(
HttpMethod.Get.Method,
"users/{userId}/addresses",
async context =>
{
var routeData = context.GetRouteData();
var userId = routeData.Values["userId"];
// userId available from here
}
);
}
Should be initiated from an application builder extension method.
public static IApplicationBuilder UseAddresses(
this IApplicationBuilder app
)
{
RouteBuilder builder = new RouteBuilder(app);
AddAddressesRoute(app, builder);
app.UseRouter(builder.Build());
return app;
}
Becomes a middleware that can be added to the Startup.Configure method just like this:
app.UseAddresses()
It doesn't even interfere with MVC that still gets triggered if the route doesn't match.
Upvotes: 2
Reputation: 1111
You can access the HttpContext from middleware and parse out key-value pairs from the query string but you can not access the path parameters via key-value.
For example:
You make a GET to the following controller via http://contoso.com/api/users/5?zip=90210
:
// GET api/users/5
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return "value";
}
Custom Middleware:
public class MyCustomMiddleware
{
public Task InvokeAsync(HttpContext context)
{
// get full path from context request path
var queryPath = context.Request.Path().ToString();
// will return /api/users/5
// get id from query string
var queryStringId = context.Request.Query["zip"].ToString();
// will return 90210
}
}
There isn't any mapping from your Controller parameters to the HttpContext.
Upvotes: 1
Reputation: 28320
URL
parsing comes to play in MVC
pipeline, not in ASP.NET Core
one.
You might want to consider MVC
filters instead, which have access to routing context.
Upvotes: 0