Dlaczego powinienem używać IHttpActionResult zamiast HttpResponseMessage?

Rozwijałem się z WebApi i przeszedłem do WebApi2, gdzie Microsoft wprowadził nowy Interfejs IHttpActionResult, który wydaje się zalecany do użycia przy zwracaniu HttpResponseMessage. Jestem zdezorientowany co do zalet tego nowego interfejsu. Wydaje się, że głównie zapewnia nieco łatwiejszy sposób tworzenia HttpResponseMessage.

Wysunąłbym argument, że jest to "abstrakcja dla abstrakcji". Coś przeoczyłem? Jakie są zalety realnego świata, które otrzymuję od korzystania z tego nowego interfejsu, poza zapisaniem linijki kodu?

Old way (WebApi):

public HttpResponseMessage Delete(int id)
{
    var status = _Repository.DeleteCustomer(id);
    if (status)
    {
        return new HttpResponseMessage(HttpStatusCode.OK);
    }
    else
    {
        throw new HttpResponseException(HttpStatusCode.NotFound);
    }
}

New Way (WebApi2):

public IHttpActionResult Delete(int id)
{
    var status = _Repository.DeleteCustomer(id);
    if (status)
    {
        //return new HttpResponseMessage(HttpStatusCode.OK);
        return Ok();
    }
    else
    {
        //throw new HttpResponseException(HttpStatusCode.NotFound);
        return NotFound();
    }
}
Author: abatishchev, 2014-02-13

8 answers

Możesz zdecydować się nie używać IHttpActionResult, ponieważ twój istniejący kod buduje HttpResponseMessage, który nie pasuje do jednej z puszkowanych odpowiedzi. Można jednak dostosować HttpResponseMessage do IHttpActionResult, używając puszki odpowiedzi ResponseMessage. Trochę mi to zajęło, więc chciałem to opublikować pokazując, że nie musisz wybierać jednego lub drugiego: {]}

public IHttpActionResult SomeAction()
{
   IHttpActionResult response;
   //we want a 303 with the ability to set location
   HttpResponseMessage responseMsg = new HttpResponseMessage(HttpStatusCode.RedirectMethod);
   responseMsg.Headers.Location = new Uri("http://customLocation.blah");
   response = ResponseMessage(responseMsg);
   return response;
}

Uwaga, ResponseMessage jest metodą klasy bazowej ApiController, od której powinien dziedziczyć twój kontroler.

 316
Author: AaronLS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-30 05:50:27

Nadal możesz używać HttpResponseMessage. Ta zdolność nie zniknie. Czułem się tak samo jak ty i spierałem się z zespołem, że nie ma potrzeby dodatkowej abstrakcji. Było kilka argumentów rzuconych wokół, aby spróbować uzasadnić jego istnienie, ale nic, co przekonało mnie, że warto.

To znaczy, dopóki nie zobaczyłemtej próbki z Brada Wilsona . Jeśli zbudujesz IHttpActionResult klasy w sposób, który można przykleić łańcuchem, zyskasz możliwość tworzenia "action-level" rurociąg odpowiedzi do generowania HttpResponseMessage. Pod pokrywami, tak są zaimplementowane ActionFilters jednak kolejność tych ActionFilters nie jest oczywista przy czytaniu metody akcji, co jest jednym z powodów, dla których nie jestem fanem filtrów akcji.

Jednak, tworząc IHttpActionResult, które mogą być bezpośrednio połączone łańcuchem w metodzie działania, możesz skomponować różne zachowania, aby wygenerować odpowiedź.

 84
Author: Darrel Miller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-31 23:25:57

Oto kilka zalet IHttpActionResult nad HttpResponseMessage wymienionych w Microsoft ASP.Net dokumentacja :

  • upraszcza jednostkowe testowanie kontrolerów.
  • przenosi wspólną logikę tworzenia odpowiedzi HTTP do osobnych klas.
  • uwidacznia intencje działania kontrolera, ukrywając niskopoziomowe szczegóły konstruowania odpowiedzi.

Ale oto kilka innych zalet korzystania z IHttpActionResult warto

  • przestrzeganie zasady pojedynczej odpowiedzialności : powoduje, że metody działania są odpowiedzialne za obsługę żądań HTTP i nie angażują ich w tworzenie wiadomości odpowiedzi HTTP.
  • użyteczne implementacje już zdefiniowane w systemie.Www.Http.Wyniki: Ok NotFound Exception Unauthorized BadRequest Conflict Redirect InvalidModelState (link do pełnej listy )
  • używa asynchronicznego i domyślnie czeka .
  • Easy tworzenie własnych ActionResult poprzez implementację metody ExecuteAsync.
  • możesz użyć ResponseMessageResult ResponseMessage(HttpResponseMessage response), aby przekonwertować HttpResponseMessage na Ihttpactionresult.
 63
Author: Behzad Bahmanyar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-27 09:59:15
// this will return HttpResponseMessage as IHttpActionResult
return ResponseMessage(httpResponseMessage); 
 32
Author: Adam Tal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-23 22:51:30

To tylko moja osobista opinia i ludzie z zespołu web API mogą prawdopodobnie wyrazić ją lepiej, ale oto mój 2c.

Po pierwsze, myślę, że nie jest to kwestia jednego nad drugim. Możesz użyć ich obu w zależności od tego, co chcesz zrobić w swojej metodzie działania, ale aby zrozumieć prawdziwą moc IHttpActionResult, prawdopodobnie będziesz musiał wyjść poza te wygodne metody pomocnicze ApiController, takie jak Ok, NotFound, itd.

W zasadzie myślę, że Klasa implementująca IHttpActionResult jako fabryka HttpResponseMessage. Z takim nastawieniem staje się teraz obiektem, który należy zwrócić i fabryką, która go produkuje. W ogólnym sensie programowania obiekt można tworzyć samodzielnie w pewnych przypadkach, a w niektórych przypadkach potrzebna jest do tego fabryka. Ja też.

Jeśli chcesz zwrócić odpowiedź, która musi być skonstruowana za pomocą złożonej logiki, powiedzmy wiele nagłówków odpowiedzi itp., Możesz streścić wszystkie te logiki w klasie wyniku działania implementującej IHttpActionResult i użyć jej w wiele metod działania, aby zwrócić odpowiedź.

Kolejną zaletą używania IHttpActionResult jako typu return jest to, że sprawia ASP.NET metoda działania Web API podobna do MVC. Możesz zwrócić dowolny wynik działania bez przechwytywania w formaterach multimedialnych.

Oczywiście, jak zauważył Darrel, można łączyć wyniki akcji i tworzyć potężny mikro-rurociąg podobny do samych programów obsługi wiadomości w potoku API. Będzie to potrzebne w zależności od złożoności działania metoda.

Krótko mówiąc-to nie IHttpActionResult kontra HttpResponseMessage. Zasadniczo jest to sposób, w jaki chcesz stworzyć odpowiedź. Zrób to sam lub przez fabrykę.

 18
Author: Badri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-13 17:28:44

Web API w zasadzie zwraca 4 typy obiektów: void, HttpResponseMessage, IHttpActionResult, i inne silne typy. Pierwsza wersja Web API zwraca HttpResponseMessage, który jest dość prostym Komunikatem odpowiedzi HTTP.

IHttpActionResult został wprowadzony przez WebAPI 2, który jest rodzajem owinięcia HttpResponseMessage. Zawiera on metodę ExecuteAsync() do tworzenia HttpResponseMessage. Upraszcza to testowanie jednostkowe kontrolera.

Inne typy zwracane są rodzajem silnych klas typowanych serializowanych przez Web API przy użyciu formatera multimediów do ciała odpowiedzi. Wadą było to, że nie można bezpośrednio zwrócić kodu błędu, takiego jak 404. Wszystko, co możesz zrobić, to rzucić HttpResponseException błąd.

 6
Author: Peter.Wang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-31 23:30:02

Wolałbym zaimplementować funkcję interfejsu TaskExecuteAsync dla IHttpActionResult. Coś w stylu:

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = _request.CreateResponse(HttpStatusCode.InternalServerError, _respContent);

        switch ((Int32)_respContent.Code)
        { 
            case 1:
            case 6:
            case 7:
                response = _request.CreateResponse(HttpStatusCode.InternalServerError, _respContent);
                break;
            case 2:
            case 3:
            case 4:
                response = _request.CreateResponse(HttpStatusCode.BadRequest, _respContent);
                break;
        } 

        return Task.FromResult(response);
    }

, Gdzie _request to HttpRequest, a _respContent to ładunek.

 3
Author: appletwo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-28 07:07:29

Mamy następujące korzyści z używania IHttpActionResult nad HttpResponseMessage:

  1. używając IHttpActionResult koncentrujemy się tylko na danych do wysłania, a nie na kodzie statusu. Więc tutaj kod będzie czystszy i bardzo łatwy w utrzymaniu.
  2. testowanie jednostkowe zaimplementowanej metody kontrolera będzie łatwiejsze.
  3. domyślnie używa async i await.
 3
Author: Debendra Dash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-31 23:31:14