В ASP.NET MVC 5 вы можете выдать HttpException с HTTP-кодом, и это установит ответ следующим образом:
throw new HttpException((int)HttpStatusCode.BadRequest, "Bad Request.");
HttpException
не существует в ASP.NET Core. Какой эквивалентный код?
В ASP.NET MVC 5 вы можете выдать HttpException с HTTP-кодом, и это установит ответ следующим образом:
throw new HttpException((int)HttpStatusCode.BadRequest, "Bad Request.");
HttpException
не существует в ASP.NET Core. Какой эквивалентный код?
Я реализовал свое собственное HttpException
и поддерживающее промежуточное ПО, которое перехватывает все HttpException
и превращает их в соответствующий ответ об ошибке. Краткий отрывок можно увидеть ниже. Вы также можете использовать пакет Boxed.AspNetCore Nuget.
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
, которое "волшебным образом" превращается в ответные сообщения.
Что вы можете сделать, подключиться к конвейеру 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<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>();
}
}
В качестве альтернативы, если вы просто хотите вернуть произвольный код состояния и не связаны с подходом, основанным на исключении, вы можете использовать
return new HttpStatusCodeResult(400);
Обновление: с .NET Core RC 2 префикс Http отбрасывается. Теперь это:
return new StatusCodeResult(400);
Базовый класс Microsoft.AspNet.Mvc.Controller
предоставляет перегрузку HttpBadRequest(string)
, которая принимает сообщение об ошибке для возврата клиенту. Поэтому из-за действия контроллера вы можете вызвать:
return HttpBadRequest("Bad Request.");
В конечном счете мой нос говорит, что любые частные методы, вызванные из действия контроллера, должны либо полностью соответствовать http-контексту, либо возвращать IActionResult
, либо выполнять какую-либо другую небольшую задачу, полностью изолированную от того факта, что она внутри конвейера http, Конечно, это мое личное мнение, но класс, который выполняет какую-то часть бизнес-логики, не должен возвращать коды статуса HTTP, а вместо этого должен бросать свои собственные исключения, которые можно поймать и перевести на уровне контроллера/действия.