web-dev-qa-db-fra.com

Comment écrire actionResult personnalisé dans le noyau asp.net

Dans webApi2, je pouvais écrire un ActionResult personnalisé en héritant IHttpActionResult.

Échantillon :

public class MenivaActionResult : IHttpActionResult
    {
        private readonly HttpRequestMessage _request;
        private readonly ServiceResponseBase _response;

        public MenivaActionResult(HttpRequestMessage request, ServiceResponseBase response)
        {
            _request = request;
            _response = response;
        }


        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken token)
        {

            HttpResponseMessage httpresponseMessage = _response.Exception != null
                ? _request.CreateErrorResponse((HttpStatusCode)_response.HttpCode,
                    _response.Exception.Message+":"+_response.Exception.HelpCode)
                : _request.CreateResponse((HttpStatusCode)_response.HttpCode, _response.Data);
            return Task.FromResult(httpresponseMessage);
        }
    }

L'objet de classe ServiceResponseBase contient toutes les exceptions et les données de la couche de service.

Comment je peux porter ce code sur le noyau asp.net. J'ai essayé mais je ne sais pas comment créer un message de réponse à partir de l'objet HttpRequestMessage dans le noyau .net. La IActionResult n'a que la méthode Task ExecuteResultAsync(ActionContext context). comment je peux modifier la réponse de cette méthode

15
Binson Eldhose

Voici un exemple:

public class TestResult
{
    public Exception Exception { get; set; }
    public object Data { get; set; }
}

public class TestActionResult : IActionResult
{
    private readonly TestResult _result;

    public TestActionResult(TestResult result)
    {
        _result = result;
    }

    public async Task ExecuteResultAsync(ActionContext context)
    {
        var objectResult = new ObjectResult(_result.Exception ?? _result.Data)
        {
            StatusCode = _result.Exception != null
                ? StatusCodes.Status500InternalServerError
                : StatusCodes.Status200OK
        };

        await objectResult.ExecuteResultAsync(context);
    }
}

ObjectResult est le type de conversion de vos résultats si vous retournez un nonIActionResult d'une action. Il fera la négociation de contenu pour vous.

Vous pouvez également hériter de ObjectResult et configurer le code d'état et les données à écrire dans le constructeur.

Plus d'informations sur la négociation de contenu dans ASP.NET Core: https://docs.Microsoft.com/en-us/aspnet/core/mvc/models/formatting#content-negotiation

26
juunas

Bien que la réponse @juunas soit techniquement correcte, ce que vous essayez vraiment de réaliser est une gestion personnalisée des erreurs. Et la meilleure façon est de découpler cette logique à l'aide du filtre d'action, du filtre middleware ou du middleware séparé (cela dépend de l'étendue que vous devez couvrir).

L'idée principale est que le contrôleur ne devrait pas être responsable de la gestion des exceptions. Il doit retourner le résultat attendu avec le statut OK ou dire que quelque chose ne va pas (exception de levée) et déléguer à d'autres parties du pipeline ce qu'il faut faire avec le problème.

Regardez SO: Gestion des erreurs dans l'API Web ASP.NET Core 1.0 (Envoi ex.Message au client) pour des exemples. Aussi Gestion des erreurs dans ASP.NET Core doc peut être utile.

2
Set