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没有HttpException
或HttpResponseException
这样的概念,“神奇地”转向响应消息。
你可以做什么, 通过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可以在控制器/操作级别被捕获和转换。
- Object.GetHashCode()的默认实现
- unit testing构造函数是否很重要?
- 为什么我的一系列结构占用了太多的内存?
- .NET数据结构:ArrayList,List,HashTable,Dictionary,SortedList,SortedDictionary – 速度,内存,以及何时使用?
- System.Array.CopyTo()和System.Array.Clone()之间的区别
- 无法从List <Bar>转换为List <Foo>
- 如何处理Datagridviewbutton列中的单击事件?
- 为什么使用try {} finally {}和空try块?
- 将parameter passing给模板types的C#genericsnew()