web-dev-qa-db-fra.com

Comment renvoyer HTTP 500 à partir de l'API Web ASP.NET Core RC2?

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?

142
Mickael Caruso

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.

187
Federico Dipuma

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);
131
Edward Comeau

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 ...

26
David McEleney

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 .

15
gldraphael
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.

12
Shimmy

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;
    }
}
8
Airn5475

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 ().

4
Tekin