ASP.NET 核心 2.2 - 问题详情
ASP.NET Core 2.2 - ProblemDetails
我最近将支持 Swagger 的 ASP.NET 核心项目升级到了 2.2。我注意到我的所有错误响应现在都显示有 ProblemDetails 响应正文。
{
"type": "string",
"title": "string",
"status": 0,
"detail": "string",
"instance": "string",
"additionalProp1": {},
"additionalProp2": {},
"additionalProp3": {}
}
根据 Microsoft 的说法,这是预期的 - 我对此很满意。
但是,由于某些原因,我的项目没有 return 这些默认 return 代码,例如 401。这是(我认为是)我的启动配置的相关部分。
services
.AddAuthentication(options => {
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(jwtOptions => {
jwtOptions.Authority = jwtConfiguration.Authority;
jwtOptions.TokenValidationParameters.ValidAudiences = jwtConfiguration.Audiences;
});
// Add framework services.
services
.AddMvcCore(options => {
options.Filters.Add<OperationCancelledExceptionFilterAttribute>();
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddAuthorization()
.AddApiExplorer()
.AddJsonFormatters()
.AddCors()
.AddJsonOptions(options => options.SerializerSettings.Converters.Add(new StringEnumConverter()));
services.AddVersionedApiExplorer(
options => {
//The format of the version added to the route URL
options.GroupNameFormat = "'v'VVV";
//Tells swagger to replace the version in the controller route
options.SubstituteApiVersionInUrl = true;
});
services.AddApiVersioning(option => {
option.ReportApiVersions = true;
});
// Add data protection
services.AddDataProtection();
//Add swagger
services.AddSwaggerGen(c => {
c.SwaggerDoc("v1", new Info { Version = "1.0", ...});
c.SwaggerDoc("v2", new Info { Version = "2.0", ...});
c.AddSecurityDefinition("Bearer", ...});
c.AddSecurityRequirement(...);
c.DescribeAllEnumsAsStrings();
c.EnableAnnotations();
});
//Add documentation for end point
services.AddSwaggerGen(...});
使用此设置,任何未经授权的请求都会以 401 结束,但不会附加任何问题详细信息。这不是我所理解的应该发生的事情,而且我无法弄清楚我需要按下哪个开关才能实现它。
默认情况下,模型验证失败时仅针对 400 个 BadRequests 问题详细信息 returned。这是通过将 ApiController 属性添加到控制器时自动插入的过滤器来完成的。在过滤器的情况下,此行为可能会受到 ApiBehaviorOptions
的影响,特别是 InvalidModelStateResponseFactory
.
发生的其他异常也没有映射到问题详细信息,因此您必须编写自己的中间件。类似于以下内容:
public class ExceptionMiddleware
{
private readonly RequestDelegate _next;
private readonly IActionResultExecutor<ObjectResult> _executor;
public ExceptionMiddleware(RequestDelegate next, IActionResultExecutor<ObjectResult> executor)
{
_next = next;
_executor = executor;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch(Exception ex)
{
await ExecuteProblemDetailsResultAsync(context, ex);
}
}
private Task ExecuteProblemDetailsResultAsync(HttpContext context, Exception ex)
{
var routeData = context.GetRouteData();
var actionContext = new ActionContext(context, routeData, new ActionDescriptor());
var problemDetails = ex.ToProblemDetails();
return _executor.ExecuteAsync(actionContext, new ObjectResult(problemDetails));
}
}
但这仍然不会 return 401 Unauthorized as Problem Details 为此,您应该在中间件中捕获 HttpResponse 并将其转换为问题详细信息。
但是因为我遇到了同样的问题并且希望我的 API 中的所有异常都被 return 编辑为问题详细信息,所以我创建了一个名为 HttpExceptions 的 NuGet 包,它可以为您做到这一点:)看看吧,也许对你来说也是一个不错的解决方案。
我最近将支持 Swagger 的 ASP.NET 核心项目升级到了 2.2。我注意到我的所有错误响应现在都显示有 ProblemDetails 响应正文。
{
"type": "string",
"title": "string",
"status": 0,
"detail": "string",
"instance": "string",
"additionalProp1": {},
"additionalProp2": {},
"additionalProp3": {}
}
根据 Microsoft 的说法,这是预期的 - 我对此很满意。
但是,由于某些原因,我的项目没有 return 这些默认 return 代码,例如 401。这是(我认为是)我的启动配置的相关部分。
services
.AddAuthentication(options => {
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(jwtOptions => {
jwtOptions.Authority = jwtConfiguration.Authority;
jwtOptions.TokenValidationParameters.ValidAudiences = jwtConfiguration.Audiences;
});
// Add framework services.
services
.AddMvcCore(options => {
options.Filters.Add<OperationCancelledExceptionFilterAttribute>();
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddAuthorization()
.AddApiExplorer()
.AddJsonFormatters()
.AddCors()
.AddJsonOptions(options => options.SerializerSettings.Converters.Add(new StringEnumConverter()));
services.AddVersionedApiExplorer(
options => {
//The format of the version added to the route URL
options.GroupNameFormat = "'v'VVV";
//Tells swagger to replace the version in the controller route
options.SubstituteApiVersionInUrl = true;
});
services.AddApiVersioning(option => {
option.ReportApiVersions = true;
});
// Add data protection
services.AddDataProtection();
//Add swagger
services.AddSwaggerGen(c => {
c.SwaggerDoc("v1", new Info { Version = "1.0", ...});
c.SwaggerDoc("v2", new Info { Version = "2.0", ...});
c.AddSecurityDefinition("Bearer", ...});
c.AddSecurityRequirement(...);
c.DescribeAllEnumsAsStrings();
c.EnableAnnotations();
});
//Add documentation for end point
services.AddSwaggerGen(...});
使用此设置,任何未经授权的请求都会以 401 结束,但不会附加任何问题详细信息。这不是我所理解的应该发生的事情,而且我无法弄清楚我需要按下哪个开关才能实现它。
默认情况下,模型验证失败时仅针对 400 个 BadRequests 问题详细信息 returned。这是通过将 ApiController 属性添加到控制器时自动插入的过滤器来完成的。在过滤器的情况下,此行为可能会受到 ApiBehaviorOptions
的影响,特别是 InvalidModelStateResponseFactory
.
发生的其他异常也没有映射到问题详细信息,因此您必须编写自己的中间件。类似于以下内容:
public class ExceptionMiddleware
{
private readonly RequestDelegate _next;
private readonly IActionResultExecutor<ObjectResult> _executor;
public ExceptionMiddleware(RequestDelegate next, IActionResultExecutor<ObjectResult> executor)
{
_next = next;
_executor = executor;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch(Exception ex)
{
await ExecuteProblemDetailsResultAsync(context, ex);
}
}
private Task ExecuteProblemDetailsResultAsync(HttpContext context, Exception ex)
{
var routeData = context.GetRouteData();
var actionContext = new ActionContext(context, routeData, new ActionDescriptor());
var problemDetails = ex.ToProblemDetails();
return _executor.ExecuteAsync(actionContext, new ObjectResult(problemDetails));
}
}
但这仍然不会 return 401 Unauthorized as Problem Details 为此,您应该在中间件中捕获 HttpResponse 并将其转换为问题详细信息。
但是因为我遇到了同样的问题并且希望我的 API 中的所有异常都被 return 编辑为问题详细信息,所以我创建了一个名为 HttpExceptions 的 NuGet 包,它可以为您做到这一点:)看看吧,也许对你来说也是一个不错的解决方案。