【发布时间】:2017-10-17 10:15:45
【问题描述】:
我有一个具有 API 的 .NET Core Web 应用程序。我已经定义了一个基于this 答案的中间件类,如下所示:
public class ErrorHandlingMiddleware
{
private readonly RequestDelegate next;
private readonly ILogger logger;
public ErrorHandlingMiddleware(RequestDelegate next,
ILoggerFactory loggerFactory)
{
this.next = next;
logger = loggerFactory.CreateLogger<ErrorHandlingMiddleware>();
}
public async Task Invoke(HttpContext context)
{
try
{
await next(context);
}
catch (Exception ex)
{
logger.LogError(0, ex, "An unhandled exception has occurred: " + ex.StackTrace);
await HandleExceptionAsync(context, ex);
}
}
private static Task HandleExceptionAsync(HttpContext context, Exception exception)
{
var code = HttpStatusCode.InternalServerError;
var message = exception.Message;
if (exception is BadRequestException)
{
code = HttpStatusCode.BadRequest;
}
else if (exception is NotFoundException)
{
code = HttpStatusCode.NotFound;
}
else if (exception is NotAuthorizedException)
{
code = HttpStatusCode.Forbidden;
}
else if (exception is NotAuthenticatedException)
{
code = HttpStatusCode.Unauthorized;
}
else
{
message = "An unexpected error occurred.";
}
var result = JsonConvert.SerializeObject(new { error = message });
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)code;
return context.Response.WriteAsync(result);
}
}
错误处理仅在代码中引发异常时处理。错误的路线不会引发异常。问题是,如果我尝试访问不存在的 API 路由(即遵循 API 路由约定并以“/api/adfasdf”开头的路由),API 会返回 HTML(或错误页面或主页,我忘了)。
我收到了一些建议在await next(context); 执行后检查context.Response.StatusCode,但它是200。
如何配置我的网络应用程序,使其识别错误的 API 路由并返回 404?
更新 这是我在 Startup 类中加载中间件的位置/时间:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime appLifetime, IOptions<OidcConfig> oidcConfigOptions)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
// Add Serilog to the logging pipeline
loggerFactory.AddSerilog();
app.UseMiddleware<ErrorHandlingMiddleware>();
if (env.IsLocal())
{
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true
});
}
var oidcConfig = oidcConfigOptions.Value;
// Configure the app to use Jwt Bearer Authentication
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
Authority = oidcConfig.GetAuthority(),
Audience = oidcConfig.ResourceAppId,
TokenValidationParameters = new TokenValidationParameters
{
RequireExpirationTime = true,
RequireSignedTokens = true,
ValidateAudience = true,
ValidIssuer = oidcConfig.GetIssuer(),
ValidateIssuer = true,
ValidateActor = false,
ValidateLifetime = true,
ValidateIssuerSigningKey = true
},
});
app.UseSiteIdClaimInjection();
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
appLifetime.ApplicationStopped.Register(() => this.ApplicationContainer.Dispose());
}
【问题讨论】:
-
您可以尝试在调用
await next(context);后立即检查context.Response.StatusCode -
@Nkosi 这就是该答案的 cmets 中所建议的。它返回一个
200。 -
不要滥用该/流控制的异常。它们是针对例外而不是针对预期结果的。
-
@im1dermike,您如何以及在管道中的何处添加中间件?这应该很早就添加到管道中,如果不是,首先添加到管道中。
-
@Nkosi 已更新。当我将其设置为 Configure() 方法中的绝对第一行时,我仍然得到 200。
标签: asp.net api asp.net-core asp.net-core-webapi