ASP.NET MVC'de ApiController ve Controller arasındaki fark


343

ASP.NET MVC 4 beta ile oynuyorum ve şimdi iki tür denetleyici görüyorum: ApiControllerve Controller.

Belirli bir denetleyiciyi hangi durumlarda seçebileceğim konusunda biraz kafam karıştı.

Örneğin: Bir görünümü geri döndürmek istersem kullanmam ApiControllermı yoksa sıradan Controllermı? WCF Web API'sının artık MVC ile entegre olduğunu biliyorum.

Şimdi her iki denetleyiciyi de kullanabileceğimizden biri, lütfen ilgili denetleyici için hangi durumlarda gidileceğini işaret edebilir.


23
Önemli: ASPNET Core 'birleştirildi' ApiControllerve Controllerbu nedenle daha yeni .NET kullanıyorsanız artık ApiController için endişelenmenize gerek yok - docs.microsoft.com/en-us/aspnet/core/tutorials/first-web- api
Simon_Weaver

Yanıtlar:


356

Normal görünümlerinizi oluşturmak için Denetleyici'yi kullanın. ApiController eylemi yalnızca serileştirilmiş ve istemciye gönderilen verileri döndürür.

bağlantı burada

Alıntı:

Not ASP.NET MVC ile çalıştıysanız, zaten denetleyicilere aşinadır. Web API'sinde benzer şekilde çalışırlar, ancak Web API'sindeki denetleyiciler, Controller sınıfı yerine ApiController sınıfından türetilir. Fark edeceğiniz ilk büyük fark, Web API denetleyicilerindeki eylemlerin görünüm döndürmemesi, veri döndürmesidir.

ApiControllers veri döndürme konusunda uzmanlaşmıştır. Örneğin, verileri istemci tarafından istenen formata şeffaf bir şekilde serileştirmeye özen gösterirler. Ayrıca, kural olarak bir REST-ful API'si sağlayarak varsayılan olarak farklı bir yönlendirme şemasını izlerler (URL'leri eylemlerle eşleme gibi).

Muhtemelen bazı (?) Manuel kodlama ile ApiController yerine bir Controller kullanarak her şeyi yapabilirsiniz. Sonunda, her iki denetleyici de ASP.NET temelini oluşturur. Ancak, REST-ful API'sine sahip olmak, bugün böyle bir API'nın uygulanmasını basitleştirmek için WebAPI'nin yaratılması gibi yaygın bir gereksinimdir.

İkisi arasında karar vermek oldukça basittir: HTML tabanlı bir web / internet / intranet uygulaması yazıyorsanız - belki ara sıra AJAX çağrısı ile json'u buraya oraya döndürürseniz - MVC / Denetleyici ile sopa. Bir sisteme veri güdümlü / REST-ful arabirimi sağlamak istiyorsanız WebAPI ile gidin. Elbette, bir MVC sayfasından ApiController cater AJAX çağrılarına sahip olan her ikisini de birleştirebilirsiniz.

Gerçek bir dünya örneği vermek için: Şu anda varlıklarına REST-ful API sağlayan bir ERP sistemi ile çalışıyorum. Bu API için WebAPI iyi bir aday olacaktır. Aynı zamanda ERP sistemi, REST-ful API için sorgular oluşturmak için kullanabileceğiniz yüksek düzeyde AJAX ified web uygulaması sağlar. Web uygulamasının kendisi, meta verileri almak için WebAPI'yi kullanarak bir MVC uygulaması olarak uygulanabilir.


9
Not: Verileriniz kablo üzerinden gönderileceğinden, nasıl biçimlendirilir? Bir ApiController'ın döndürdüğü verilerin biçimlendirilmesi içerik anlaşması ve GlobalConfiguration.Configuration.Formatters ... bağlantısı tarafından belirlenir: link: blogs.msdn.com/b/kiranchalla/archive/2012/02/25/…
Tim Lovell-Smith

1
Web API'sının web sitesi, mobil vb. İçin ortak bir Platform olduğunu söylemek doğru mu? ve Web API yerine Sınıf Kitaplığı kullanabilir miyiz?
Imad Alazani

Notunuz için teşekkürler @ TimLovell-Smith, çünkü benim için Andre soruyu cevaplamıyor: Bir Denetleyici de veri döndürebildiğinden, ApiController'ın neden var olduğunu ve yararlı olduğunu açıklamıyor.
JYL

2
@JYL Daha ayrıntılı bilgi vermek için cevabımı artırdım.
Andre Loker

2
"Kongre ile bir REST-ful API sağlama" dediğinde gerçekten anlamadım . REST-ful API'yi nasıl sağlar? API'dan hangi verilere geri döndüğünüze bağlı değil mi? Denetleyicide API'yi REST-ful olmaya zorlayan (hatta kolaylaştıran) hiçbir şey yoktur.
Nawaz

192

Hangisini yazmayı ve sürdürmeyi tercih edersiniz?

ASP.NET MVC

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

ASP.NET Web API'sı

public class TweetsController : ApiController {
  // GET: /Api/Tweets/
  public List<Tweet> Get() {
    return Twitter.GetTweets();
  }
}

6
İyi bir nokta ama ApiController sadece JSON serileştirmesinden daha fazlası. Ayrıca, kabul türü ise isteğe bakmak ve XML döndürmekle de ilgilenir.
Jake Almer

10
Asp.net çekirdeği kullanırsanız, hepsi Controllersınıftan türetilir .
Tan

2
Bu eski örnekler gibi görünüyor, Şimdi ApiControllersadece : Controllerişler hakkında endişelenmemiz gerekmiyor , yeni dot net core Controller örneği de ekleyebilir misiniz
Ashish Kamble

@AshishKamble, ApiController yerine ControllerBase kullanılıyor.
Vladimir Shiyanov

Dürüst olmak gerekirse, Json()versiyona sahip olmayı tercih ederim . Daha net ve daha açık. Kodumun bir isteğe nasıl yanıt vereceğini anlamaya çalışırken bir sürü kara büyü sevmiyorum.
Jez

27

ASP.NET Core'un MVC6'sının iki deseni bir araya getirdiği gerçeğini seviyorum, çünkü genellikle her iki dünyayı da desteklemem gerekiyor. Herhangi bir standart MVC'yi Controller(ve / veya kendi ActionResultsınıflarınızı geliştirmek ) tıpkı bir gibi davranıp davranmak için düzenleyebileceğiniz doğru ApiControllerolsa da, korumak ve test etmek çok zor olabilir: bunun da ötesinde , Kontrolör yöntemlerinin ActionResultbaşkalarıyla karıştırılması ham / serileştirilmiş / IHttpActionResultveri döndürmek , özellikle yalnız çalışmıyorsanız ve diğer geliştiricileri bu hibrit yaklaşımla hızlandırmak için geliştirici bakış açısından çok kafa karıştırıcı olabilir.

ASP.NET Core olmayan web uygulamalarında bu sorunu en aza indirgemek için şimdiye kadarki en iyi teknik Web API paketini MVC tabanlı Web Uygulamasına aktarmak (ve düzgün bir şekilde yapılandırmak), böylece her ikisinin de en iyisini elde edebiliyorum dünyalar: ControllersGörünümler ApiControllersiçin, veri için.

Bunu yapmak için aşağıdakileri yapmanız gerekir:

  • NuGet kullanarak aşağıdaki Web API paketlerini kurun: Microsoft.AspNet.WebApi.Coreve Microsoft.AspNet.WebApi.WebHost.
  • Klasörünüze bir veya daha fazla ApiController ekleyin /Controllers/.
  • Aşağıdaki WebApiConfig.cs dosyasını /App_Config/klasörünüze ekleyin :

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 }
        );
    }
}

Son olarak, yukarıdaki sınıfı Başlangıç sınıfınıza kaydetmeniz gerekir (ya Startup.csda Global.asax.cs, OWIN Başlangıç ​​şablonunu kullanıp kullanmadığınıza bağlı olarak).

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);
    // ...
}

Bu yaklaşım - artıları ve eksileri ile birlikte - bloguma yazdığım bu yazıda daha fazla açıklanıyor .


1
iyi bir şey. ancak bu işlev zaten vs2015 ile yerleşiktir. webapi asp.net projesi oluşturursanız, tüm kazan plaka kodunu sizin için otomatik olarak yapar.
suomi-dev

@Darkseal lütfen "bakımı ve testi çok zor olabilir" hakkında biraz ayrıntı verebilir misiniz? (Blog yazınızı okudum) WebAPI2 kullandım ve nasıl çalıştığını seviyorum. Ancak, “gerçek büyük fayda” nın yanında “bir şeyler yapmanın ortak yolu” nu anlayamıyorum. Klasik MVC denetleyicilerinin "el ile" serileştirilmiş dizeleri döndürmesi yeterince kolaydır. Http Accept fiiliyle bir json / xml anahtarı eklemek fazla zaman almaz. Tüm bunlar güzel bir yardımcı program yöntemine sarılabilir.
ValGe

2
@ValGe, yukarıdaki @ manish-jain cevabına bakınız. Özetle, Controlleriçine sarılmış bir Json serileştirilmiş dize döndürmek ActionResult, test etmek ve korumak için kesinlikle daha zordur ve ApiControllerbu bir [Serializable]öğe listesini doğrudan döndürecek şekilde ayarlanabilir . Herhangi bir test yönteminin yazılması çok daha kolay olacaktır, çünkü her seferinde manuel olarak serileştirmeyi kaldırmak zorunda kalmayacaksınız: ASP.NET veya diğer çerçevelerle neredeyse tüm sistem entegrasyon görevleri için aynı şey söylenebilir. Controllersharika, ancak ApiControllersen azından .NET Framework 4.x'te RESTful görevleri için daha uygundur
Darkseal

1

Web API'sindeki her yöntem seri hale getirilmeden veri (JSON) döndürür.

Ancak, MVC denetleyicilerinde JSON Verilerini döndürmek için, döndürülen Eylem Sonuç türünü JsonResult olarak ayarlayacağız ve JSON'da paketlendiğinden emin olmak için nesnemizdeki Json yöntemini çağıracağız.


1

Temel fark şudur: Web API, herhangi bir istemci, herhangi bir cihaz için bir hizmettir ve MVC Denetleyici yalnızca istemcisine hizmet eder. Aynı şey MVC platformudur.


-1

İkisi arasında karar vermek oldukça basittir: HTML tabanlı bir web / internet / intranet uygulaması yazıyorsanız - belki ara sıra AJAX çağrısı ile json'u buraya oraya döndürürseniz - MVC / Denetleyici ile sopa. Bir sisteme veri güdümlü / REST-ful arabirimi sağlamak istiyorsanız WebAPI ile gidin. Elbette, bir MVC sayfasından ApiController cater AJAX çağrılarına sahip olan her ikisini de birleştirebilirsiniz. Temelde denetleyici mvc için kullanılır ve api-denetleyici Rest-API için kullanılır ve her ikisini de ihtiyacınız olanla aynı programda kullanabilirsiniz

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.