c# - handling - return json from web api asp net core
¿Cómo devolver HTTP 500 desde ASP.NET Core RC2 Web Api? (7)
De vuelta en RC1, haría esto:
[HttpPost]
public IActionResult Post([FromBody]string something)
{
try{
// ...
}
catch(Exception e)
{
return new HttpStatusCodeResult((int)HttpStatusCode.InternalServerError);
}
}
En RC2, ya no hay HttpStatusCodeResult, y no hay nada que pueda encontrar que me permita devolver un tipo 500 de IActionResult.
¿El enfoque ahora es completamente diferente a lo que estoy preguntando?
¿Ya no intentamos atrapar el código del
Controller
?
¿Dejamos que el marco arroje una excepción genérica 500 al llamador API?
Para el desarrollo, ¿cómo puedo ver la pila de excepción exacta?
¿Qué tal crear una clase ObjectResult personalizada que represente un error interno del servidor como el de
OkObjectResult
?
Puede poner un método simple en su propia clase base para que pueda generar fácilmente InternalServerError y devolverlo como lo hace con
Ok()
o
BadRequest()
.
Response.StatusCode = (int)HttpStatusCode.InternalServerError;//Equals to HTTPResponse 500
return Json(new { responseText = "my error" });
Cuando desee devolver una respuesta JSON en MVC .Net Core También puede usar:
Response.StatusCode = (int)HttpStatusCode.InternalServerError;//Equals to HTTPResponse 500 return Json(new { responseText = "my error" });
Esto devolverá el resultado JSON y HTTPStatus. Lo uso para devolver resultados a jQuery.ajax ().
Por lo que puedo ver, hay métodos auxiliares dentro de la clase
ControllerBase
.
Simplemente use el método
StatusCode
:
[HttpPost]
public IActionResult Post([FromBody] string something)
{
//...
try
{
DoSomething();
}
catch(Exception e)
{
LogException(e);
return StatusCode(500);
}
}
También puede usar la
StatusCode(int statusCode, object value)
que también negocia el contenido.
Puede usar
Microsoft.AspNetCore.Mvc.ControllerBase.StatusCode
y
Microsoft.AspNetCore.Http.StatusCodes
para formar su respuesta, si no desea codificar números específicos.
return StatusCode(StatusCodes.Status500InternalServerError);
ACTUALIZACIÓN: agosto de 2019
Quizás no esté directamente relacionado con la pregunta original, pero al intentar lograr el mismo resultado con las
Microsoft Azure Functions
descubrí que tenía que construir un nuevo objeto
StatusCodeResult
que se encuentra en el ensamblado
Microsoft.AspNetCore.Mvc.Core
.
Mi código ahora se ve así;
return StatusCode(StatusCodes.Status500InternalServerError, responseObject);
Si necesita un cuerpo en su respuesta, puede llamar
app.UseExceptionHandler("/Error");
Esto devolverá un 500 con el objeto de respuesta ...
Una mejor manera de manejar esto a partir de ahora (1.1) es hacer esto en
Startup.cs
''s
Configure()
:
[Route("[controller]")]
public class ErrorController : Controller
{
[Route("")]
[AllowAnonymous]
public IActionResult Get()
{
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
Esto ejecutará la ruta para
/Error
.
Esto le ahorrará agregar bloques try-catch a cada acción que escriba.
Por supuesto, deberá agregar un ErrorController similar a este:
// 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
}
Más información here .
En caso de que desee obtener los datos de excepción reales, puede agregarlos al
Get()
anterior justo antes de la declaración de
return
.
return StatusCode((int)HttpStatusCode.InternalServerError, e);
Fragmento anterior tomado del blog de Scott Sauber .
[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;
}
}
Debe usarse en contextos que no sean ASP.NET (ver otras respuestas para ASP.NET Core).
HttpStatusCode
es una enumeración en
System.Net
.