De retour dans RC1, je voudrais faire ceci:
[HttpPost]
public IActionResult Post([FromBody]string something)
{
try{
// ...
}
catch(Exception e)
{
return new HttpStatusCodeResult((int)HttpStatusCode.InternalServerError);
}
}
Dans RC2, HttpStatusCodeResult n'existe plus, et rien ne me permet de retrouver un type 500 de IActionResult.
L'approche est-elle maintenant totalement différente de ce que je demande? N'essayons-nous plus dans le code Controller
? Laissons-nous simplement la structure renvoyer une exception générique 500 à l'appelant API? Pour le développement, comment puis-je voir la pile d'exceptions exacte?
D'après ce que je peux voir, il existe des méthodes d'assistance à l'intérieur de la classe ControllerBase
. Utilisez simplement la méthode StatusCode
:
[HttpPost]
public IActionResult Post([FromBody] string something)
{
//...
try
{
DoSomething();
}
catch(Exception e)
{
LogException(e);
return StatusCode(500);
}
}
Vous pouvez également utiliser la surcharge StatusCode(int statusCode, object value)
qui négocie également le contenu.
Vous pouvez utiliser Microsoft.AspNetCore.Mvc.ControllerBase.StatusCode
et Microsoft.AspNetCore.Http.StatusCodes
pour former votre réponse, si vous ne souhaitez pas coder en dur des nombres spécifiques.
return StatusCode(StatusCodes.Status500InternalServerError);
MISE À JOUR: août 2019
Peut-être pas directement lié à la question initiale, mais en essayant d'obtenir le même résultat avec Microsoft Azure Functions
, j'ai constaté que je devais construire un nouvel objet StatusCodeResult
trouvé dans l'assemblage Microsoft.AspNetCore.Mvc.Core
. Mon code ressemble maintenant à ceci;
return new StatusCodeResult(StatusCodes.Status500InternalServerError);
Si vous avez besoin d'un corps dans votre réponse, vous pouvez appeler
return StatusCode(StatusCodes.Status500InternalServerError, responseObject);
Cela retournera un 500 avec l'objet de réponse ...
Une meilleure façon de gérer cela à partir de maintenant (1.1) est de le faire dans Startup.cs
'Configure()
:
app.UseExceptionHandler("/Error");
Ceci exécutera la route pour /Error
. Cela vous évitera d'ajouter des blocs try-catch à chaque action que vous écrivez.
Bien sûr, vous devrez ajouter un ErrorController similaire à ceci:
[Route("[controller]")]
public class ErrorController : Controller
{
[Route("")]
[AllowAnonymous]
public IActionResult Get()
{
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
Plus d'informations ici .
Si vous souhaitez obtenir les données d’exception réelles, vous pouvez les ajouter à la Get()
ci-dessus juste avant l’instruction 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
}
Extrait ci-dessus tiré de blog de Scott Sauber .
return StatusCode((int)HttpStatusCode.InternalServerError, e);
Devrait être utilisé dans des contextes non-ASP.NET (voir les autres réponses concernant ASP.NET Core).
HttpStatusCode
est une énumération dans System.Net
.
Pourquoi ne pas créer une classe ObjectResult personnalisée qui représente une erreur de serveur interne telle que celle de OkObjectResult
? Vous pouvez mettre une méthode simple dans votre propre classe de base afin de pouvoir facilement générer InternalServerError et le renvoyer exactement comme vous le faites Ok()
ou 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;
}
}
Lorsque vous souhaitez renvoyer une réponse JSON dans MVC .Net Core, vous pouvez également utiliser:
Response.StatusCode = (int)HttpStatusCode.InternalServerError;//Equals to HTTPResponse 500
return Json(new { responseText = "my error" });
Cela renverra à la fois le résultat JSON et HTTPStatus. Je l'utilise pour renvoyer les résultats à jQuery.ajax ().