Różnica między ApiController a kontrolerem w ASP.NET MVC

343

Bawiłem się z ASP.NET MVC 4 beta i teraz widzę dwa typy kontrolerów: ApiControlleri Controller.

Nie jestem zdezorientowany, w jakich sytuacjach mogę wybrać konkretnego kontrolera.

Na przykład: jeśli chcę zwrócić widok, muszę użyć ApiControllerlub zwykłego Controller? Wiem, że interfejs API sieci WCF jest teraz zintegrowany z MVC.

Ponieważ teraz możemy korzystać z obu kontrolerów, ktoś może wskazać, w jakich sytuacjach wybrać odpowiedni kontroler.

VJAI
źródło
23
Ważne: ASPNET rdzeń „połączył” ApiController, a Controllerwięc jeśli używasz nowszej .NET nie trzeba się martwić o ApiController już - docs.microsoft.com/en-us/aspnet/core/tutorials/first-web- api
Simon_Weaver,
2
Cieszę się, że tak! Tak długo przewidywałem przy okazji prideparrot.com/blog/archive/2012/10/asp_net_mvc_vs_webapi
VJAI

Odpowiedzi:

356

Użyj kontrolera, aby renderować swoje normalne widoki. Działanie ApiController zwraca tylko dane, które są serializowane i wysyłane do klienta.

tutaj jest link

Zacytować:

Uwaga Jeśli pracujesz z ASP.NET MVC, znasz już kontrolery. Działają podobnie w Web API, ale kontrolery w Web API pochodzą z klasy ApiController zamiast z klasy Controller. Pierwszą znaczącą różnicą, którą zauważysz, jest to, że działania na kontrolerach interfejsu API sieci Web nie zwracają widoków, tylko dane.

ApiControllery specjalizują się w zwracaniu danych. Na przykład dbają o przejrzystą serializację danych do formatu żądanego przez klienta. Ponadto domyślnie stosują inny schemat routingu (jak w: mapowanie adresów URL na działania), zapewniając zgodnie z konwencją interfejs API REST.

Prawdopodobnie możesz zrobić wszystko przy użyciu kontrolera zamiast ApiController z niektórymi (?) Kodowaniami ręcznymi. Ostatecznie oba kontrolery bazują na platformie ASP.NET. Ale posiadanie interfejsu API REST jest dzisiaj tak powszechnym wymogiem, że interfejs WebAPI został utworzony w celu uproszczenia implementacji takiego interfejsu API.

Wybór między tymi dwoma jest dość prosty: jeśli piszesz aplikację internetową / internetową / intranetową opartą na HTML - być może przy sporadycznym wywołaniu AJAX zwracającym json tu i tam - trzymaj się MVC / kontrolera. Jeśli chcesz zapewnić systemowi interfejs oparty na danych / REST, skorzystaj z WebAPI. Można oczywiście połączyć oba, mając ApiController obsługujący wywołania AJAX ze strony MVC.

Podam przykład z prawdziwego świata: Obecnie pracuję z systemem ERP, który zapewnia interfejs API REST dla swoich podmiotów. W przypadku tego interfejsu API WebAPI byłby dobrym kandydatem. Jednocześnie system ERP zapewnia aplikację internetową o wysokim stopniu zaawansowania AJAX, której można używać do tworzenia zapytań do interfejsu API REST. Sama aplikacja internetowa może zostać zaimplementowana jako aplikacja MVC, wykorzystująca interfejs WebAPI do pobierania metadanych itp.

Andre Loker
źródło
9
Uwaga: ponieważ dane będą przesyłane przewodowo, w jaki sposób zostaną sformatowane? Sposób formatowania danych zwracanych przez ApiController zależy od negocjacji treści i GlobalConfiguration.Configuration.Formatters ... link: blogs.msdn.com/b/kiranchalla/archive/2012/02/25/…
Tim Lovell-Smith
1
Czy słuszne jest stwierdzenie, że interfejs API sieci Web jest powszechną platformą dla witryn internetowych, urządzeń mobilnych itp.? i czy moglibyśmy użyć Biblioteki klas zamiast Web API?
Imad Alazani,
Dzięki @ TimLovell-Smith za notatkę, ponieważ dla mnie Andre nie odpowiada na pytanie: ponieważ kontroler może również zwracać dane, nie wyjaśnia, dlaczego ApiController istnieje i jest przydatny.
JYL
2
@JYL Ulepszyłem swoją odpowiedź, aby podać bardziej szczegółowe informacje.
Andre Loker,
2
Naprawdę nie rozumiałem, kiedy powiedziałeś „zapewnianie interfejsu API REST-full zgodnie z konwencją” . Jak zapewnia API REST-ful? Czy to nie zależy od tego, jakie dane zwracasz z interfejsu API? W kontrolerze nie ma nic, co zmusiłoby (lub nawet ułatwiło) API do bycia REST.
Nawaz
192

Który wolisz pisać i utrzymywać?

ASP.NET MVC

public class TweetsController : Controller {
  // GET: /Tweets/
  [HttpGet]
  public ActionResult Index() {
    return Json(Twitter.GetTweets(), JsonRequestBehavior.AllowGet);
  }
}

ASP.NET Web API

public class TweetsController : ApiController {
  // GET: /Api/Tweets/
  public List<Tweet> Get() {
    return Twitter.GetTweets();
  }
}
Manish Jain
źródło
6
To dobry punkt, ale ApiController to coś więcej niż tylko serializacja JSON. Zajmuje się również sprawdzaniem żądania i zwracaniem XML, jeśli jest to typ akceptacji.
Jake Almer,
10
Jeśli używasz asp.net core, wszystkie z nich pochodzą z Controllerklasy.
Tân
2
Wydaje się, że są to stare przykłady. Teraz nie musimy się martwić, że ApiControllerpo prostu : Controllerdziałają, czy możesz dodać także nowy przykład kontrolera rdzenia sieci kropkowej
Ashish Kamble
@AshishKamble, zamiast ApiController używana jest teraz ControllerBase.
Vladimir Shiyanov
Szczerze mówiąc wolałbym mieć Json()wersję. Jest jaśniejsze i bardziej jednoznaczne. Nie podoba mi się mnóstwo czarnej magii, próbując dowiedzieć się, jak mój kod zareaguje na żądanie.
Jez
27

Uwielbiam fakt, że MVC6 programu ASP.NET Core połączył oba wzorce w jeden, ponieważ często muszę obsługiwać oba światy. Chociaż prawdą jest, że możesz dostosować dowolny standardowy MVC Controller(i / lub opracować własne ActionResultklasy), aby zachowywał się i zachowywał tak jak on ApiController, może być jednak bardzo trudny do utrzymania i przetestowania: na dodatek mieszanie metod kontrolerówActionResult z innymi zwracanie nieprzetworzonych / zserializowanych / IHttpActionResultdanych może być bardzo mylące z punktu widzenia programisty, szczególnie jeśli nie pracujesz sam i potrzebujesz przyspieszyć innych programistów dzięki temu hybrydowemu podejściu.

Najlepszą techniką, jaką do tej pory doszedłem do zminimalizowania tego problemu w nie-podstawowych aplikacjach internetowych ASP.NET, jest zaimportowanie (i poprawne skonfigurowanie) pakietu Web API do aplikacji internetowej opartej na MVC, dzięki czemu mogę mieć to, co najlepsze z obu światy: Controllersdla widoków, ApiControllersdla danych.

Aby to zrobić, musisz wykonać następujące czynności:

  • Zainstaluj następujące pakiety interfejsu API sieci Web za pomocą NuGet: Microsoft.AspNet.WebApi.Corei Microsoft.AspNet.WebApi.WebHost.
  • Dodaj jeden lub więcej ApiControllerów do swojego /Controllers/folderu.
  • Dodaj następujący plik WebApiConfig.cs do swojego /App_Config/folderu:

using System.Web.Http;

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

Wreszcie, trzeba zarejestrować powyższą klasę do uruchomienia klasy (albo Startup.csalbo Global.asax.cs, zależnie od tego czy używasz szablonu OWIN startowy lub nie).

Startup.cs

 public void Configuration(IAppBuilder app)
 {
    // Register Web API routing support before anything else
    GlobalConfiguration.Configure(WebApiConfig.Register);

    // The rest of your file goes there
    // ...
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    ConfigureAuth(app);
    // ...
}

Global.asax.cs

protected void Application_Start()
{
    // Register Web API routing support before anything else
    GlobalConfiguration.Configure(WebApiConfig.Register);

    // The rest of your file goes there
    // ...
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    // ...
}

Podejście to - wraz z jego zaletami i wadami - wyjaśniono szerzej w tym poście, który napisałem na moim blogu.

Darkseal
źródło
1
dobra rzecz. ale ta funkcja jest już wbudowana w vs2015. jeśli utworzysz projekt webapi asp.net, automatycznie wykona dla ciebie cały kod płyty kotłowej.
suomi-dev,
@Darkseal, czy mógłbyś rozwinąć nieco temat „może być bardzo trudny w utrzymaniu i przetestowaniu”? (Przeczytałem twój post na blogu) Użyłem WebAPI2 i podoba mi się, jak to działa. Jednak nie mogę zrozumieć „prawdziwej dużej korzyści” oprócz tego, że jest to „wspólny sposób robienia rzeczy”. Posiadanie klasycznych kontrolerów MVC zwracających „ręcznie” serializowane ciągi znaków jest dość łatwe. Dodanie przełącznika json / xml za pomocą czasownika http Accept nie zajmuje dużo. Wszystko to można spakować w miłą metodę użyteczności. Dzięki.
ValGe
2
@ValGe, patrz @ odpowiedź manish-jain powyżej. Krótko mówiąc, Controllerzwracanie łańcucha z serializacją ActionResultJsona owiniętego wewnątrz jest zdecydowanie trudniejsze do przetestowania i utrzymania niż takie, ApiControllerktóre można ustawić tak, aby bezpośrednio zwracało listę [Serializable]elementów. Każda metoda testowa byłaby o wiele łatwiejsza do napisania, ponieważ nie trzeba za każdym razem ręcznie usuwać serializacji: to samo można powiedzieć o prawie każdym zadaniu integracji systemu z ASP.NET lub innymi platformami. Controllerssą świetne, ale ApiControllerslepiej nadają się do zadań RESTful, przynajmniej w .NET Framework 4.x
Darkseal
1

Każda metoda w interfejsie API sieci Web zwraca dane (JSON) bez serializacji.

Aby jednak zwrócić dane JSON w kontrolerach MVC, ustawimy zwracany typ wyniku działania na JsonResult i wywołamy metodę Json na naszym obiekcie, aby upewnić się, że jest on spakowany w JSON.

Shailesh Uke
źródło
1

Główna różnica polega na tym, że: Web API to usługa dla dowolnego klienta, dowolnego urządzenia, a MVC Controller obsługuje tylko swojego klienta. To samo, ponieważ jest to platforma MVC.

ANJYR - KODEXPRESSION
źródło
-1

Wybór między tymi dwoma jest dość prosty: jeśli piszesz aplikację internetową / internetową / intranetową opartą na HTML - być może przy sporadycznym wywołaniu AJAX zwracającym json tu i tam - trzymaj się MVC / kontrolera. Jeśli chcesz zapewnić systemowi interfejs oparty na danych / REST, skorzystaj z WebAPI. Można oczywiście połączyć oba, mając ApiController obsługujący wywołania AJAX ze strony MVC. Zasadniczo kontroler służy do mvc, a kontroler interfejsu API służy do Rest-API, którego można używać zarówno w tym samym programie, jak potrzebujesz


źródło