dotnet / dotnet/aspnetcore

No dynamic paths for UseStatusCodePages and UseExceptionHandler

Open
#18,383 3 comments 3 reactions 0 assignees View on GitHub
affected-very-few area-middleware enhancement severity-minor
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

### Is your feature request related to a problem? Please describe.
Currently UseStatusCodePages and UseExceptionHandler methods support only one handler path. But there are cases when handler path can vary depending on some conditions. For example, I have different areas and handler path should depend on the area name.

### Describe the solution you'd like
Built-in extensions methods for ExceptionHandlerMiddleware and StatusCodePagesMiddleware should exist that accept path generation functions. For example, for UseStatusCodePagesWithReExecute it can be something like that:
```
public static IApplicationBuilder UseStatusCodePagesWithReExecute(
this IApplicationBuilder app,
Func generatePath,
Func generateQuery = null)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}

return app.UseStatusCodePages(async context =>
{
var newPath = generatePath(context);
var newQueryString = generateQuery == null ? QueryString.Empty : new QueryString(generateQuery(context));

var originalPath = context.HttpContext.Request.Path;
var originalQueryString = context.HttpContext.Request.QueryString;
// Store the original paths so the app can check it.
context.HttpContext.Features.Set(new StatusCodeReExecuteFeature()
{
OriginalPathBase = context.HttpContext.Request.PathBase.Value,
OriginalPath = originalPath.Value,
OriginalQueryString = originalQueryString.HasValue ? originalQueryString.Value : null,
});

// An endpoint may have already been set. Since we're going to re-invoke the middleware pipeline we need to reset
// the endpoint and route values to ensure things are re-calculated.
context.HttpContext.SetEndpoint(endpoint: null);
var routeValuesFeature = context.HttpContext.Features.Get();
routeValuesFeature?.RouteValues?.Clear();

context.HttpContext.Request.Path = newPath;
context.HttpContext.Request.QueryString = newQueryString;
try
{
await context.Next(context.HttpContext);
}
finally
{
context.HttpContext.Request.QueryString = originalQueryString;
context.HttpContext.Request.Path = originalPath;
context.HttpContext.Features.Set(null);
}
});
}
}
```

I hope such methods will be added soon :)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.