Как вернуть HTTP 500 из ASP.NET Core RC2 Web Api?
Вернувшись в RC1, я бы сделал это:
[HttpPost]
public IActionResult Post([FromBody]string something)
{
try{
// ...
}
catch(Exception e)
{
return new HttpStatusCodeResult((int)HttpStatusCode.InternalServerError);
}
}
В RC2 больше нет HttpStatusCodeResult, и я не могу найти ничего, что позволило бы мне возвращать тип 500 типа IActionResult.
Подход сейчас совершенно другой для того, что я спрашиваю? Разве мы больше не пытаемся поймать код Controller
? Мы просто позволяем фреймворку генерировать общее исключение 500 обратно в вызывающую функцию API? Для разработки, как я могу увидеть точный стек исключений?
Ответы
Ответ 1
Из того, что я вижу, есть вспомогательные методы внутри класса ControllerBase
. Просто используйте метод StatusCode
:
[HttpPost]
public IActionResult Post([FromBody] string something)
{
//...
try
{
DoSomething();
}
catch(Exception e)
{
LogException(e);
return StatusCode(500);
}
}
Вы также можете использовать StatusCode(int statusCode, object value)
которая также согласовывает содержимое.
Ответ 2
Вы можете использовать Microsoft.AspNetCore.Mvc.ControllerBase.StatusCode
и Microsoft.AspNetCore.Http.StatusCodes
для формирования своего ответа, если вы не хотите указывать конкретные номера.
return StatusCode(StatusCodes.Status500InternalServerError);
Ответ 3
Лучший способ справиться с этим на данный момент (1.1) - сделать это в Startup.cs
Configure()
:
app.UseExceptionHandler("/Error");
Это выполнит маршрут для /Error
. Это избавит вас от добавления блоков try-catch к каждому написанному вами действию.
Конечно, вам нужно добавить ErrorController, подобный этому:
[Route("[controller]")]
public class ErrorController : Controller
{
[Route("")]
[AllowAnonymous]
public IActionResult Get()
{
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
Больше информации здесь.
Если вы хотите получить фактические данные об исключении, вы можете добавить их в приведенный выше Get()
прямо перед оператором return
.
// Get the details of the exception that occurred
var exceptionFeature = HttpContext.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionFeature != null)
{
// Get which route the exception occurred at
string routeWhereExceptionOccurred = exceptionFeature.Path;
// Get the exception that occurred
Exception exceptionThatOccurred = exceptionFeature.Error;
// TODO: Do something with the exception
// Log it with Serilog?
// Send an e-mail, text, fax, or carrier pidgeon? Maybe all of the above?
// Whatever you do, be careful to catch any exceptions, otherwise you'll end up with a blank page and throwing a 500
}
Выше фрагмент взят из блога Скотта Саубера.
Ответ 4
return StatusCode((int)HttpStatusCode.InternalServerError, e);
Должен использоваться в не-ASP.NET контекстах (см. Другие ответы для ASP.NET Core).
HttpStatusCode
- это перечисление в System.Net
.
Ответ 5
Если вам нужно тело в вашем ответе, вы можете позвонить
return StatusCode(StatusCodes.Status500InternalServerError, responseObject);
Это вернет 500 с объектом ответа...
Ответ 6
вы можете вернуть BadRequestResult или StatusCodeResult, то есть:
return new BadRequestResult();
или
return new StatusCodeResult(500)
Ответ 7
Как насчет создания пользовательского класса ObjectResult, который представляет внутреннюю ошибку сервера, например, для OkObjectResult
? Вы можете поместить простой метод в свой собственный базовый класс, чтобы вы могли легко сгенерировать InternalServerError и вернуть его так же, как вы делаете Ok()
или BadRequest()
.
[Route("api/[controller]")]
[ApiController]
public class MyController : MyControllerBase
{
[HttpGet]
[Route("{key}")]
public IActionResult Get(int key)
{
try
{
//do something that fails
}
catch (Exception e)
{
LogException(e);
return InternalServerError();
}
}
}
public class MyControllerBase : ControllerBase
{
public InternalServerErrorObjectResult InternalServerError()
{
return new InternalServerErrorObjectResult();
}
public InternalServerErrorObjectResult InternalServerError(object value)
{
return new InternalServerErrorObjectResult(value);
}
}
public class InternalServerErrorObjectResult : ObjectResult
{
public InternalServerErrorObjectResult(object value) : base(value)
{
StatusCode = StatusCodes.Status500InternalServerError;
}
public InternalServerErrorObjectResult() : this(null)
{
StatusCode = StatusCodes.Status500InternalServerError;
}
}
Ответ 8
return StatusCodes.Status500InternalServerError;