In the ExceptionHandler
middleware, the Response
is cleared before being passed into your own middleware function, as can be seen in the source:
try
{
await _next(context);
}
catch (Exception ex)
{
// ...
context.Response.Clear();
// ...
await _options.ExceptionHandler(context);
// ..
}
Of course, this means that any response headers that might have been set in respect to CORS are also being cleared.
The following code plugs in to the general CORS system, and I believe does appear to mostly satisfy your requirement that the configuration from ConfigureServices
can be used:
var corsService = httpContext.RequestServices.GetService<ICorsService>();
var corsPolicyProvider = httpContext.RequestServices.GetService<ICorsPolicyProvider>();
var corsPolicy = await corsPolicyProvider.GetPolicyAsync(httpContext, null);
corsService.ApplyResult(
corsService.EvaluatePolicy(httpContext, corsPolicy),
httpContext.Response);
GetPolicyAsync
takes the name of a policy as the second parameter - If this is null (as in my example), it will use the default policy, if this has been set up.
I've not included null-checks or anything in the code example, in order to keep it focussed, but this approach is working in a test project I have built.
This approach is heavily influenced by the CorsAuthorizationFilter source code in Microsoft.AspNetCore.Mvc.Cors.
EDIT: You're not using a named policy in your example code, but you can switch over to one using the following:
.AddCors(corsOptions => corsOptions.AddPolicy(
"Default",
corsPolicyBuilder => corsPolicyBuilder
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()));
This uses AddPolicy
- I mentioned AddDefaultPolicy
in the comments, but it looks like this is not in the current release and so not available yet. With the changes above, you can just call UseCors
like so:
app.UseCors("Default");
The final change is to update to the following in your exception handling code:
await corsPolicyProvider.GetPolicyAsync(httpContext, "Default");
You'd be better off using some sort of const string for this, especially as it's likely all running from the same file. The main change here is no longer attempting to use the default named policy, as I was looking at the current version of the source code on GitHub that is yet to be released.