Création de nouvelles méthodes de résultats

Est-il une manière que je peux utiliser la nouvelle IHttpActionResult interface pour retourner un HttpStatusCode.NoContent message de réponse?

j'utilise actuellement return new HttpResponseMessage( HttpStatusCode.NoContent ); et voudrais le convertir en fichier return NoContent();.

IHttpActionResult a déjà eu Ok(),Conflict() et NotFound() mais je ne trouve aucune pour Forbidden() et NoContent() lequel j'utilise dans mon projet.

Comment est-il facile d'ajouter d'autres types de résultats?

29
demandé sur Liam 2015-02-05 14:46:06

4 réponses

il n'y a pas de méthode pratique pour no-content résultat, parce que, par défaut, lorsqu'une action est de retour void, la réponse aura le statut HTTP 204.

Si vous souhaitez indiquer explicitement que sur l'action, vous pouvez également revenir un StatusCode(HttpStatusCode.NoContent) à partir de votre action ou un

ResponseMessage(new HttpResponseMessage(HttpStatusCode.NoContent)).

la méthode convenience non autorisée() Vous donne un statut 401 donc, pour Forbidden (403), vous devriez aussi utiliser StatusCode(HttpStatusCode.Forbidden) ou

ResponseMessage(new HttpResponseMessage(HttpStatusCode.Forbidden))
40
répondu Rafael Companhoni 2017-05-15 23:31:20

j'ai trouvé ce exemple de site qui montre comment ajouter un custom IHttpActionResult méthode et j'ai utilisé ceci pour créer le Forbidden() et NoContent() méthodes avec grand succès.

public abstract class CommonApiController : ApiController
{
    public class ForbiddenResult : IHttpActionResult
    {
        private readonly HttpRequestMessage _request;
        private readonly string _reason;

        public ForbiddenResult(HttpRequestMessage request,string reason)
        {
            _request = request;
            _reason = reason;
        }

        public ForbiddenResult(HttpRequestMessage request)
        {
            _request = request;
            _reason = "Forbidden";
        }

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            var response = _request.CreateResponse(HttpStatusCode.Forbidden,_reason);
            return Task.FromResult(response);
        }
    }

    public class NoContentResult : IHttpActionResult
    {
        private readonly HttpRequestMessage _request;
        private readonly string _reason;

        public NoContentResult(HttpRequestMessage request,string reason)
        {
            _request = request;
            _reason = reason;
        }

        public NoContentResult(HttpRequestMessage request)
        {
            _request = request;
            _reason = "No Content";
        }

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            var response = _request.CreateResponse(HttpStatusCode.NoContent,_reason);
            return Task.FromResult(response);
        }
    }
}

Et puis je peux l'utiliser comme ceci:

public class InvoiceController : CommonApiController
{
    public async Task<IHttpActionResult> Post([FromBody]Invoice invoice)
    {
        if(User.IsInRole("Readonly"))
        {
            return Forbidden();
        }

        // Rest of code

    }
}
23
répondu Intrepid 2015-02-06 08:20:35

j'ai essayé l'implémentation de @Intrepid et j'ai rencontré quelques problèmes. Je vois ici deux solutions:

Solution 1: La partie: return Forbidden(); ne devrait pas fonctionner.

le compilateur ne reconnaîtrait pas cela.

au Lieu de cela, il devrait être: return new ForbiddenResult(Request, "my reason");

UPDATE 1

Solution 2:

je pense que c'est ce que @Interpid voulait dans son implémentation, mais il en manquait quelques uns chose.

afin d'utiliser return Forbidden();CommonApiController doit être mis à jour avec les fonctions qui renvoient la coutume IHttpActionResultForbidden et NoContent

La classe devrait ressembler à ceci:

public abstract class CommonApiController: ApiController {

    protected ForbiddenResult Forbidden() {
     return new ForbiddenResult(this.Request);
    }

    protected ForbiddenResult Forbidden(string reason) {
     return new ForbiddenResult(this.Request, reason);
    }

    protected NoContentResult NoContent() {
     return new NoContentResult(this.Request);
    }

    protected NoContentResult NoContent(string reason) {
     return new NoContentResult(this.Request, reason);
    }

    public class ForbiddenResult: IHttpActionResult {
     private readonly HttpRequestMessage _request;
     private readonly string _reason;

     public ForbiddenResult(HttpRequestMessage request, string reason) {
      _request = request;
      _reason = reason;
     }

     public ForbiddenResult(HttpRequestMessage request) {
      _request = request;
      _reason = "Forbidden";
     }

     public Task < HttpResponseMessage > ExecuteAsync(CancellationToken cancellationToken) {
      var response = _request.CreateResponse(HttpStatusCode.Forbidden, _reason);
      return Task.FromResult(response);
     }
    }

    public class NoContentResult: IHttpActionResult {
     private readonly HttpRequestMessage _request;
     private readonly string _reason;

     public NoContentResult(HttpRequestMessage request, string reason) {
      _request = request;
      _reason = reason;
     }

     public NoContentResult(HttpRequestMessage request) {
      _request = request;
      _reason = "No Content";
     }

     public Task < HttpResponseMessage > ExecuteAsync(CancellationToken cancellationToken) {
      var response = _request.CreateResponse(HttpStatusCode.NoContent, _reason);
      return Task.FromResult(response);
     }
    }
   }

en tout cas, si je me trompe et que la réponse de @Interpid est correcte. Qu'est-ce qui me manque ici pour que sa mise en œuvre fonctionne?

7
répondu Asaf Epelbaum 2017-08-10 09:13:13

si vous voulez inclure une phrase de raison dans votre réponse sans ajouter de sous-classe à ApiController, construisez un objet Responsiemessage et renvoyez-le de l'action par la méthode Responsiemessage (). Essayez ceci:

public class InvoiceController : ApiController
{
    public async Task<IHttpActionResult> Post([FromBody]Invoice invoice)
    {
        if(User.IsInRole("Readonly"))
        {
            var response = new HttpResponseMessage(HttpStatusCode.Forbidden);

            response.ReasonPhrase = "User has the Readonly role";
            return ResponseMessage(response);
        }

        // Rest of code

    }
}
3
répondu kmac.mcfarlane 2015-07-23 15:51:26