-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Service to recalculate endpoint to execute with endpoint routing #30549
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
https://github.com/dotnet/aspnetcore/blob/7bbaec1512682ab2a8f7d82440bc2bb428cc1857/src/Http/Routing/src/EndpointRoutingMiddleware.cs does use DI resolved services to match routes, but some of them are internal like MatcherFactory. It looks like it would be possible to wrap that logic in a public service. |
That'd be much appreciated. |
@javiercn can you share some writeup about how this can be done, if it's easy? Thanks! |
@mkArtakMSFT I think we'd need to expose public API here... |
My first suggestion would be to perform the url rewrite before If for some reason that is not possible, I would try using a matcher policy to do it by:
If you can provide a more concrete example I can probably offer more targeted guidance. |
Well, it's part of IdentityServer's middleware. By default IdentityServer when it receives an authorization request and needs to render a response as HTML to post results back to a client it would normally render some hard coded HTML, but the customer might want their own (styling, branding, etc), so to achieve this I thought it'd be quite nice to re-execute in the pipeline to hit one of their endpoints (razor, MVC, whatever) to allow them to render the HTML. |
@brockallen I see. I think there might be a better way to do that. The way I would go about it is as follows:
If all you care is about being able to override the emitted response, that's the best way to go about it. |
Actually, it can be a bit simpler than what I'm suggesting. Assuming that you aren't using endpoint routing, in your middleware, when you hit the path, resolve the EndpointDataSource and search for an endpoint with your metadata on it (a controller with an attribute basically) and call context.SetEndpoint(endpoint) and that should do it. Or check if the current selected endpoint has the metadata and noop in that case (let it override and handle the response) and produce a default otherwise. |
Right, this solution basically means your middleware can inspect the selected endpoint (if any) and check if it has the right metadata to override the response. It does mean that the user needs to register the route with the right information (path and metadata). |
if("/my/original/path"){
var endpoint = context.GetEndpoint();
if(endpoint == null){
// Execute default response logic
}else{
if(endpoint.Metadata.OfType<MyMetadata>().Any())
{
// let the endpoint override an execute
}else
{
throw InvalidOperationException("Overriden by mistake.");
}
}
} |
What if I don't know what endpoint they want to implement to supply this response processing? I was going to allow them to configure a path to rewrite the request to if they wanted to use this feature. If they did not, then we'd fall back to our default implementation. I think it would feel odd for them to to be forced to register an endpoint for our middleware's authorization path (i.e. ~/connect/authorize"). |
@brockallen in that case the best approach is to use a middleware to rewrite the path before The problem with "recalculating" the route is that middleware before your middleware doesn't get to see the "real" endpoint. If the target uses endpoint routing you can search for the endpoint in the EndpointDataSource and set the endpoint on the request (same problem as described above, middleware before it doesn't get to see the actual endpoint) and if you don't find an endpoint then you can probably just replace the path. In my opinion, the most correct way to handle this is via a redirect or a rewrite before app.UseRouting |
My middleware doesn't care much about this custom endpoint, other than to know to execute it (which I was going to use a
Hmm... since I want the pit of success to allow customers to put our middleware before or after I could try this: In our middleware when I detect the conditions I need to do this re-writing, I'd use a forked pipeline. In the fork I would I will first call I guess in essence this means that in ASP.NET Core we can't really achieve the same thing as old-school ASP.NET's |
RewritePath - Sure, if you change the order, its not like you could rewrite the path in EndRequest. You need to do it at the right phase and in this case, that's before routing. RemapHandler - This is like setting the end point on a request. |
Perhaps my explanation wasn't clear enough on my use case or assumptions about the rewritten path. The original request path is what needs to be the logical endpoint for purposes of EP routing and all the features it brings. The the rewritten path is never meant to be seen by other middleware in the pipeline -- it's just an implementation detail of the processing of the original path and only sometimes does it need to then trigger this downstream rewritten path to generate the response. |
Thank you for contacting us. Due to a lack of activity on this discussion issue we're closing it in an effort to keep our backlog clean. If you believe there is a concern related to the ASP.NET Core framework, which hasn't been addressed yet, please file a new issue. This issue will be locked after 30 more days of inactivity. If you still wish to discuss this subject after then, please create a new issue! |
Is there a way to cause endpoint routing to re-calculate the endpoint that is to be executed? Perhaps as a service in DI?
My Scenario:
I have a middleware that is often registered after
UseRouting
. During request processing I have the need to re-write the request so it changes the request path (e.g. from/foo
to/bar
), but once the next middleware is executed which eventually ends up atUseEndpoints
we get a 404 due to the now mismatched path.I'd love a service in DI to help with this that I can trigger from my middleware.
The text was updated successfully, but these errors were encountered: