.Net Core:从自定义异常中间件返回 IActionResult
Posted
技术标签:
【中文标题】.Net Core:从自定义异常中间件返回 IActionResult【英文标题】:.Net Core: Return IActionResult from a custom Exception Middleware 【发布时间】:2020-04-05 05:25:13 【问题描述】:我在我的 .Net Core 应用程序中创建了一个新的异常中间件。整个应用程序中的所有异常都在此处捕获和记录。我想要的是从异常中间件返回一个像 InternalServerError() 或 NotFound() 这样的 IActionResult 类型,而不是像下面那样做 response.WriteAsync。
控制器方法:
public async Task<IActionResult> Post()
//Do Something
return Ok();
中间件:
public class ExceptionMiddleware
private readonly RequestDelegate _next;
public ExceptionMiddleware(RequestDelegate next)
_next = next;
public async Task Invoke(HttpContext context)
try
await _next.Invoke(context);
catch (Exception ex)
await HandleExceptionAsync(context, ex);
private async Task HandleExceptionAsync(HttpContext context, Exception exception)
var response = context.Response;
var statusCode = (int)HttpStatusCode.InternalServerError;
var message = exception.Message;
var description = exception.Message;
response.ContentType = "application/json";
response.StatusCode = statusCode;
await response.WriteAsync(JsonConvert.SerializeObject(new ErrorResponse
Message = message,
Description = description
));
【问题讨论】:
【参考方案1】:IActionResult
是来自 MVC 的东西,因此它仅在 MVC 管道(包括 Razor 页面)中可用。就在 MVC 中间件终止之前,它将使用ExecuteAsync
执行这些操作结果。然后该方法负责将该响应写入HttpContext.Response
。
因此,在自定义中间件中,您不能只设置操作结果并执行它,因为您不在 MVC 管道中运行。但是,有了这些知识,您就可以简单地自己执行结果。
假设您要执行NotFoundResult
,这是Controller.NotFound()
创建的。因此,您创建该结果并使用 .该执行器将能够执行该结果对象并写入响应:
var result = new NotFoundResult();
await result.ExecuteAsync(new ActionContext
HttpContext = context,
);
【讨论】:
【参考方案2】:这实际上是不可能的,因为IActionResult
和中间件在架构中彼此相关。中间件的位置要低得多,因此它无法在堆栈中进一步到达IActionResult
。这是一个更多地谈论它的答案:https://***.com/a/43111292/12431728
【讨论】:
【参考方案3】:只需添加以下行即可完成您想要做的事情:
app.UseStatusCodePagesWithReExecute("/Public/Error", "?statusCode=0");
到 Startup.cs 中的 Configure 方法。然后,您可以使用执行以下操作的 Error 方法创建您的公共控制器:
[AllowAnonymous]
public IActionResult Error(int? statusCode = null)
// Retrieve error information in case of internal errors.
var error = HttpContext.Features.Get<IExceptionHandlerFeature>()?.Error;
var path = HttpContext.Features.Get<IExceptionHandlerPathFeature>()?.Path;
// TODO: Redirect here based on your status code or perhaps just render different views for different status codes.
还有另一个中间件可以让你做类似的事情:
app.UseStatusCodePages(async context =>
if (context.HttpContext.Response.StatusCode == 401)
context.HttpContext.Response.Redirect("Errors/Unauthorized/");
else if (context.HttpContext.Response.StatusCode == 500)
// TODO: Redirect for 500 and so on...
);
【讨论】:
以上是关于.Net Core:从自定义异常中间件返回 IActionResult的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Core Data 获取请求从自定义 UITableViewCell 返回空?