c# - .net 核心对 API 和网页控制器的不同错误处理
问题描述
我正在尝试在新的 .net Core 2.2 Web 应用程序项目中设置异常处理。
目前我尝试了两种方法 - 成为
- 使用内置的 ExceptionHandlers:
app.UseExceptionHandler
,app.UseStatusCodePages
, 等等... - 创建了我自己的中间件来处理我添加到这个问题底部的异常。
现在,主要问题是我可以使用我自己的自定义中间件,但是(当然)这用于所有请求,而不仅仅是 API 调用。
我想要实现的是将 Web API 和网页的异常逻辑分开,这样我就可以使用我的自定义中间件和 API 的返回格式,app.UseDeveloperExceptionPage()
例如用于网页。
异常中间件供参考:
public static class ExceptionMiddleware
{
public static void ConfigureExceptionHandler(this IApplicationBuilder app, ILoggerFactory loggerFactory,
bool includeStackTrace = false)
{
app.UseExceptionHandler(builder =>
builder.Run(async context =>
{
var logger = loggerFactory.CreateLogger(nameof(ExceptionMiddleware));
// Set the response status code
context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
context.Response.ContentType = "application/json";
var contextFeature = context.Features.Get<IExceptionHandlerFeature>();
if (contextFeature != null)
{
// Get the current exception
var currentException = contextFeature.Error;
logger.LogError(currentException, $"Something went wrong: {currentException}");
ErrorDetails errorDetails;
if (includeStackTrace)
errorDetails = new ExtendedErrorDetails
{
StatusCode = (HttpStatusCode) context.Response.StatusCode,
Message = currentException.Message,
StackTrace = currentException.StackTrace
};
else
errorDetails = new ErrorDetails
{
StatusCode = (HttpStatusCode) context.Response.StatusCode,
Message = "Internal Server Error."
};
// Write the response
await context.Response.WriteAsync(JsonConvert.SerializeObject(errorDetails));
}
}));
}
private class ErrorDetails
{
public HttpStatusCode StatusCode { [UsedImplicitly] get; set; }
public string Message { [UsedImplicitly] get; set; }
}
private class ExtendedErrorDetails : ErrorDetails
{
public string StackTrace { [UsedImplicitly] get; set; }
}
}
解决方案
您无法从异常中识别错误,我建议您尝试为 mvc 和 web api 制定不同的路线。对于 web api,添加属性路由api
,然后检查中间件或异常处理程序中的请求路径,如
app.UseExceptionHandler(builder =>
{
builder.Run(async context =>
{
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
var error = context.Features.Get<IExceptionHandlerFeature>() as ExceptionHandlerFeature;
var requestPath = error.Path;
});
});
更新:
app.UseDeveloperExceptionPage();
app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), subApp =>
{
subApp.UseExceptionHandler(builder =>
{
builder.Run(async context =>
{
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
await context.Response.WriteAsync("Error");
});
});
});
推荐阅读
- python - 如何使用没有 .paste() 类的 PIL 将透明图像放入另一个图像
- typescript - 为什么类型化的字符串文字在 TypeScript 中被视为(纯)字符串?
- javascript - 限制 jQuery select2 最大可见(未选择)选项
- c# - 主导入(使用)文件c#
- c++ - C ++ - 记录集中的访问字段
- vba - 使用 VBA 将一个特定文件夹复制到另一个文件夹
- node.js - 如何在 Kubernetes/OpenShift 的容器内通过管道传输日志输出?
- discord.js - (节点:24)UnhandledPromiseRejectionWarning:TypeError:无法读取属性'send' of null
- ios - 如何将生成的 xcode 项目保存为工件
- ios - 在层次结构中显示列表视图