ASP.NET 5 / MVC 6 эквивалент HttpException

В MVC 5 вы можете передать HttpException с кодом HTTP, и это ответ будет таким:

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, который позволяет вам необязательно включить эту функцию при создании нового проекта (просто установите флажок, чтобы включить его).

     // 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(); } } 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(); 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 которое «волшебным образом» переходит на ответные сообщения.

    Что вы можете сделать, подключитесь к конвейеру ASP.NET 5 через MiddleWare и создайте тот, который обрабатывает исключения для вас.

    Вот пример из исходного кода промежуточного программного обеспечения обработчика ошибок, который установит код состояния ответа на 500 в случае исключения дальше по конвейеру:

     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(); 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(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(); } } 

    В качестве альтернативы, если вы просто хотите вернуть произвольный код состояния и не связаны с подходом, основанным на исключении, вы можете использовать

     return new HttpStatusCodeResult(400); 

    Обновление: с .NET Core RC 2 префикс Http отпадает. Сейчас:

     return new StatusCodeResult(400); 

    Базовый class Microsoft.AspNet.Mvc.Controller предоставляет HttpBadRequest(string) которая принимает сообщение об ошибке для возврата к клиенту. Поэтому из-за действия controllerа вы можете позвонить:

     return HttpBadRequest("Bad Request."); 

    В конце концов, мой нос говорит, что любые частные методы, вызванные из действия controllerа, должны либо полностью соответствовать http-контексту, либо возвращать IActionResult , либо выполнять какую-либо другую небольшую задачу, полностью изолированную от того факта, что она находится внутри конвейера http. Конечно, это мое личное мнение, но class, который выполняет какую-то часть бизнес-логики, не должен возвращать коды статуса HTTP, а вместо этого должен бросать свои собственные исключения, которые можно поймать и перевести на уровне controllerа / действия.

    Давайте будем гением компьютера.