ASP.NET 5 / MVC 6相当于HttpException

在MVC 5中,您可以使用HTTP代码来引发HttpException,并将其设置为如下所示:

throw new HttpException((int)HttpStatusCode.BadRequest, "Bad Request."); 

HttpException在ASP.NET 5 / MVC 6中不存在。什么是等效代码?

我实现了自己的HttpException并支持捕获所有HttpException的中间件,并将它们转换为相应的错误响应。 下面可以看到一个简短的摘录:

您可以使用Boilerplate.AspNetCore Nuget包,或者您可以查看以下ASP.NET MVC Boilerplate GitHub项目的完整源代码,或者使用ASP.NET MVC Boilerplate项目模板创build一个新项目,该模板允许您可选地打开此function当创build一个新的项目(只需选中该框,将其打开)。

 // Usage example in Startup.cs public void Configure(IApplicationBuilder application) { application.UseIISPlatformHandler(); application.UseStatusCodePagesWithReExecute("/error/{0}"); application.UseHttpException(); application.UseMvc(); } public static class ApplicationBuilderExtensions { public static IApplicationBuilder UseHttpException(this IApplicationBuilder application) { return application.UseMiddleware<HttpExceptionMiddleware>(); } } internal class HttpExceptionMiddleware { private readonly RequestDelegate next; public HttpExceptionMiddleware(RequestDelegate next) { this.next = next; } public async Task Invoke(HttpContext context) { try { await this.next.Invoke(context); } catch (HttpException httpException) { context.Response.StatusCode = httpException.StatusCode; var responseFeature = context.Features.Get<IHttpResponseFeature>(); responseFeature.ReasonPhrase = httpException.Message; } } } public class HttpException : Exception { private readonly int httpStatusCode; public HttpException(int httpStatusCode) { this.httpStatusCode = httpStatusCode; } public HttpException(HttpStatusCode httpStatusCode) { this.httpStatusCode = (int)httpStatusCode; } public HttpException(int httpStatusCode, string message) : base(message) { this.httpStatusCode = httpStatusCode; } public HttpException(HttpStatusCode httpStatusCode, string message) : base(message) { this.httpStatusCode = (int)httpStatusCode; } public HttpException(int httpStatusCode, string message, Exception inner) : base(message, inner) { this.httpStatusCode = httpStatusCode; } public HttpException(HttpStatusCode httpStatusCode, string message, Exception inner) : base(message, inner) { this.httpStatusCode = (int)httpStatusCode; } public int StatusCode { get { return this.httpStatusCode; } } } 

在与@davidfowl聊天之后 ,似乎ASP.NET 5没有HttpExceptionHttpResponseException这样的概念,“神奇地”转向响应消息。

你可以做什么, 通过MiddleWare挂钩到ASP.NET 5pipe道中 ,并创build一个为你处理exception。

下面是一个error handling中间件源代码的例子,它将把响应状态代码设置为500,以防进一步发生exception:

 public class ErrorHandlerMiddleware { private readonly RequestDelegate _next; private readonly ErrorHandlerOptions _options; private readonly ILogger _logger; public ErrorHandlerMiddleware(RequestDelegate next, ILoggerFactory loggerFactory, ErrorHandlerOptions options) { _next = next; _options = options; _logger = loggerFactory.CreateLogger<ErrorHandlerMiddleware>(); if (_options.ErrorHandler == null) { _options.ErrorHandler = _next; } } public async Task Invoke(HttpContext context) { try { await _next(context); } catch (Exception ex) { _logger.LogError("An unhandled exception has occurred: " + ex.Message, ex); if (context.Response.HasStarted) { _logger.LogWarning("The response has already started, the error handler will not be executed."); throw; } PathString originalPath = context.Request.Path; if (_options.ErrorHandlingPath.HasValue) { context.Request.Path = _options.ErrorHandlingPath; } try { var errorHandlerFeature = new ErrorHandlerFeature() { Error = ex, }; context.SetFeature<IErrorHandlerFeature>(errorHandlerFeature); context.Response.StatusCode = 500; context.Response.Headers.Clear(); await _options.ErrorHandler(context); return; } catch (Exception ex2) { _logger.LogError("An exception was thrown attempting to execute the error handler.", ex2); } finally { context.Request.Path = originalPath; } throw; // Re-throw the original if we couldn't handle it } } } 

你需要用StartUp.cs注册它:

 public class Startup { public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory) { app.UseMiddleWare<ExceptionHandlerMiddleware>(); } } 

另外,如果你只是想返回一个任意的状态码而不关心基于Exception的方法,你可以使用

 return new HttpStatusCodeResult(400); 

更新:从.NET Core RC 2起,Http前缀被删除。 就是现在:

 return new StatusCodeResult(400); 

Microsoft.AspNet.Mvc.Controller基类公开一个HttpBadRequest(string)重载,它HttpBadRequest(string)错误消息返回给客户端。 所以从一个控制器动作中,你可以调用:

 return HttpBadRequest("Bad Request."); 

最终,我的鼻子说,在一个控制器动作中调用的任何私有方法应该是完全HTTP上下文感知,并返回一个IActionResult ,或者执行一个完全孤立于httppipe道内的事实的其他小任务。 当然,这是我个人的看法,但是执行某些业务逻辑的类不应该返回HTTP状态代码,而应该抛出自己的exception,这些exception可以在控制器/操作级别被捕获和转换。