我有一个标准的ASP.NET Core 2 Web应用程序,用作REST/WebApi。对于我的其中一个端点,当用户提供错误的搜索/筛选查询字符串参数时,我返回一个
在POSTMAN中运行得很好。但是当我尝试使用我的SPA应用程序进行测试(实际上现在跨域,并因此进行CORS请求),我在Chrome中失败了。
当对返回
看起来我的错误处理没有考虑CORS的事情(即没有添加任何CORS头),并且没有包括那个。 我猜测我弄乱了响应负载管道的东西。 问:是否有一种方法可以在自定义错误处理程序中返回任何CORS头信息,而不是硬编码头信息,而是使用在
HTTP 400
。在POSTMAN中运行得很好。但是当我尝试使用我的SPA应用程序进行测试(实际上现在跨域,并因此进行CORS请求),我在Chrome中失败了。
当对返回
HTTP 200
响应的端点进行CORS请求时,一切都正常。看起来我的错误处理没有考虑CORS的事情(即没有添加任何CORS头),并且没有包括那个。 我猜测我弄乱了响应负载管道的东西。 问:是否有一种方法可以在自定义错误处理程序中返回任何CORS头信息,而不是硬编码头信息,而是使用在
Startup.cs
中设置的头信息?
伪代码...public void ConfigureServices(IServiceCollection services)
{
... snip ...
services.AddMvcCore()
.AddAuthorization()
.AddFormatterMappings()
.AddJsonFormatters(options =>
{
options.ContractResolver = new CamelCasePropertyNamesContractResolver();
options.Formatting = Formatting.Indented;
options.DateFormatHandling = DateFormatHandling.IsoDateFormat;
options.NullValueHandling = NullValueHandling.Ignore;
options.Converters.Add(new StringEnumConverter());
})
.AddCors(); // REF: https://learn.microsoft.com/en-us/aspnet/core/security/cors#setting-up-cors
... snip ...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
... snip ...
app.UseExceptionHandler(options => options.Run(async httpContext => await ExceptionResponseAsync(httpContext, true)));
app.UseCors(builder => builder//.WithOrigins("http://localhost:52383", "http://localhost:49497")
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod());
... snip ...
}
private static async Task ExceptionResponseAsync(HttpContext httpContext, bool isDevelopmentEnvironment)
{
var exceptionFeature = httpContext.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionFeature == null)
{
// An unknow and unhandled exception occured. So this is like a fallback.
exceptionFeature = new ExceptionHandlerFeature
{
Error = new Exception("An unhandled and unexpected error has occured. Ro-roh :~(.")
};
}
await ConvertExceptionToJsonResponseAsyn(exceptionFeature,
httpContext.Response,
isDevelopmentEnvironment);
}
private static Task ConvertExceptionToJsonResponseAsyn(IExceptionHandlerPathFeature exceptionFeature,
HttpResponse response,
bool isDevelopmentEnvironment)
{
if (exceptionFeature == null)
{
throw new ArgumentNullException(nameof(exceptionFeature));
}
if (response == null)
{
throw new ArgumentNullException(nameof(response));
}
var exception = exceptionFeature.Error;
var includeStackTrace = false;
var statusCode = HttpStatusCode.InternalServerError;
var error = new ApiError();
if (exception is ValidationException)
{
statusCode = HttpStatusCode.BadRequest;
foreach(var validationError in ((ValidationException)exception).Errors)
{
error.AddError(validationError.PropertyName, validationError.ErrorMessage);
}
}
else
{
// Final fallback.
includeStackTrace = true;
error.AddError(exception.Message);
}
if (includeStackTrace &&
isDevelopmentEnvironment)
{
error.StackTrace = exception.StackTrace;
}
var json = JsonConvert.SerializeObject(error, JsonSerializerSettings);
response.StatusCode = (int)statusCode;
response.ContentType = JsonContentType;
// response.Headers.Add("Access-Control-Allow-Origin", "*"); <-- Don't want to hard code this.
return response.WriteAsync(json);
}
祝愿大家好运!
corsPolicy = await corsPolicyProvider.GetPolicyAsync(httpContext, null);
这一部分,但它一直返回null
(导致ApplyResult
崩溃)。我没有手动设置任何策略名称,我认为这意味着代码默认使用DefaultPolicyName
... 因此将null
传递给GetPolicyAsync
应该会使用默认名称 ... 并从中解析出来? - Pure.Kromenull
而不是默认值。为了让它正常工作,看起来你可以在AddCors
中使用AddDefaultPolicy
而不是AddPolicy
(假设你正在使用AddPolicy
)。 - Kirk LarkinAddDefaultPolicy
.... - Pure.Krome