ความแตกต่างระหว่าง ApiController และคอนโทรลเลอร์ใน ASP.NET MVC


343

ฉันได้รับการเล่นรอบกับ ASP.NET MVC 4 รุ่นเบต้าและผมเห็นสองประเภทของการควบคุมขณะนี้: และApiControllerController

ฉันสับสนเล็กน้อยว่าสถานการณ์ใดที่ฉันสามารถเลือกคอนโทรลเลอร์ได้

ตัวอย่างเช่น: ถ้าฉันต้องการส่งคืนมุมมองฉันต้องใช้ApiControllerหรือControllerไม่? ฉันทราบว่า WCF Web API ได้รวมเข้ากับ MVC แล้ว

ตั้งแต่ตอนนี้เราสามารถใช้ตัวควบคุมทั้งสองได้ใครสักคนโปรดชี้ไปที่สถานการณ์ที่จะไปสำหรับตัวควบคุมที่เกี่ยวข้อง


23
สำคัญ: ASPNET หลักได้ 'รวม' ApiControllerและControllerดังนั้นหากคุณกำลังใช้ใหม่ .NET คุณไม่จำเป็นต้องกังวลเกี่ยวกับ ApiController อีกต่อไป - docs.microsoft.com/en-us/aspnet/core/tutorials/first-web- api
Simon_Weaver

2
ดีใจที่พวกเขาทำ! ฉันคาดการณ์สิ่งนี้ไว้ได้นานโดยวิธีที่ภูมิใจที่จะได้รับจากบล็อก /archive/2012/10/asp_net_mvc_vs_webapi
VJAI

คำตอบ:


356

ใช้ตัวควบคุมเพื่อแสดงมุมมองปกติของคุณ การกระทำของ ApiController จะส่งคืนข้อมูลที่ต่อเนื่องและส่งไปยังไคลเอนต์เท่านั้น

นี่คือลิงค์

อ้างถึง:

หมายเหตุถ้าคุณทำงานกับ ASP.NET MVC แสดงว่าคุณคุ้นเคยกับคอนโทรลเลอร์แล้ว พวกมันทำงานคล้ายกันใน Web API แต่ตัวควบคุมใน Web API สืบทอดมาจากคลาส ApiController แทนคลาส Controller ความแตกต่างที่สำคัญอันดับแรกที่คุณจะสังเกตเห็นคือการกระทำบนตัวควบคุม Web API จะไม่ส่งคืนมุมมอง แต่จะส่งคืนข้อมูล

ApiControllers มีความเชี่ยวชาญในการส่งคืนข้อมูล ตัวอย่างเช่นพวกเขาดูแลข้อมูลที่เป็นลำดับอย่างโปร่งใสในรูปแบบที่ลูกค้าร้องขอ นอกจากนี้พวกเขายังทำตามรูปแบบการกำหนดเส้นทางที่แตกต่างกันตามค่าเริ่มต้น (ใน: การจับคู่ URL กับการกระทำ) โดยให้ REST-ful API ตามการประชุม

คุณสามารถทำอะไรก็ได้โดยใช้คอนโทรลเลอร์แทน ApiController ที่มีการเข้ารหัสด้วยตนเอง (?) ในท้ายที่สุดตัวควบคุมทั้งสองจะสร้างบนพื้นฐาน ASP.NET แต่การมี REST-ful API นั้นเป็นข้อกำหนดทั่วไปในปัจจุบันที่ WebAPI ถูกสร้างขึ้นเพื่อทำให้การใช้ API นั้นง่ายขึ้น

มันค่อนข้างง่ายในการตัดสินใจระหว่างสอง: ถ้าคุณกำลังเขียนแอปพลิเคชันบนเว็บ / อินเทอร์เน็ต / อินทราเน็ต HTML - บางทีด้วยการโทร AJAX ที่กลับมาเป็นครั้งคราว json ที่นี่และที่นั่น - ติดกับ MVC / Controller หากคุณต้องการจัดเตรียมข้อมูลที่ขับเคลื่อนด้วย / REST-ful ส่วนต่อประสานกับระบบให้ไปที่ WebAPI คุณสามารถรวมทั้งสองอย่างเข้าด้วยกันโดยให้ ApiController ตอบสนองการโทร AJAX จากหน้า MVC

เพื่อยกตัวอย่างโลกแห่งความจริง: ขณะนี้ฉันกำลังทำงานกับระบบ ERP ที่ให้ REST-ful API แก่หน่วยงานของตน สำหรับ API นี้ WebAPI จะเป็นตัวเลือกที่ดี ในขณะเดียวกันระบบ ERP ยังมีแอปพลิเคชั่นเว็บ AJAX-ified สูงซึ่งคุณสามารถใช้เพื่อสร้างคิวรีสำหรับ REST-ful API เว็บแอปพลิเคชันสามารถนำไปใช้เป็นแอปพลิเคชั่น MVC โดยใช้ WebAPI เพื่อดึงข้อมูลเมตาเป็นต้น


9
หมายเหตุ: เนื่องจากข้อมูลของคุณจะถูกส่งผ่านสายสัญญาณจะมีการจัดรูปแบบอย่างไร ข้อมูลวิธีที่ผลตอบแทน ApiController ถูกจัดรูปแบบจะถูกกำหนดโดยการเจรจาต่อรองเนื้อหาและ GlobalConfiguration.Configuration.Formatters ... เชื่อมโยง: blogs.msdn.com/b/kiranchalla/archive/2012/02/25/...
ทิมโลเวลล์สมิ ธ

1
ถูกต้องหรือไม่ที่จะบอกว่า Web API เป็นแพลตฟอร์มทั่วไปสำหรับเว็บไซต์มือถือ ฯลฯ และเราสามารถใช้ Class Library แทน Web API ได้หรือไม่
Imad Alazani

ขอบคุณ @ TimLovell-Smith สำหรับบันทึกย่อของคุณเพราะสำหรับฉัน Andre ไม่ตอบคำถาม: เนื่องจากคอนโทรลเลอร์สามารถส่งคืนข้อมูลได้มันไม่ได้อธิบายว่าทำไม ApiController ถึงมีอยู่จริงและมีประโยชน์
JYL

2
@JYL ฉันเติมคำตอบของฉันเพื่อให้ข้อมูลรายละเอียดเพิ่มเติม
Andre Loker

2
ผมไม่เข้าใจจริงๆเมื่อคุณกล่าวว่า"การให้ API REST-ful โดยการประชุม" มันให้ REST-ful API อย่างไร ไม่ได้ขึ้นอยู่กับข้อมูลที่คุณส่งคืนจาก API หรือไม่ ไม่มีสิ่งใดในคอนโทรลเลอร์ที่บังคับ (หรือแม้แต่ช่วยอำนวยความสะดวก) API ให้เป็น REST-ful
นาวาซ

192

คุณอยากเขียนและบำรุงรักษาแบบไหน

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

6
มันเป็นจุดที่ดี แต่ ApiController เป็นมากกว่าการทำให้เป็นอันดับ JSON นอกจากนี้ยังดูแลการดูคำขอและส่งคืน XML หากเป็นประเภทการยอมรับ
Jake Almer

10
หากคุณใช้แกน asp.net ทั้งหมดจะได้รับมาจากControllerชั้นเรียน
Tân

2
นี้ดูเหมือนว่าตัวอย่างเก่าตอนนี้เราไม่จำเป็นต้องกังวลเกี่ยวกับApiControllerเพียงแค่: Controllerผลงานที่คุณสามารถเพิ่ม Dot Net หลักควบคุมตัวอย่างใหม่เกินไป
Ashish Kamble

@AshishKamble, แทนที่จะเป็น ApiController ตอนนี้ใช้ ControllerBase
Vladimir Shiyanov

สุจริตฉันต้องการมีJson()รุ่น มันชัดเจนและชัดเจนยิ่งขึ้น ฉันไม่ชอบเวทมนต์ดำจำนวนหนึ่งในการพยายามคิดออกว่าโค้ดของฉันจะตอบสนองต่อคำขอได้อย่างไร
Jez

27

ฉันชอบความจริงที่ว่า MVC6 ของ ASP.NET Core ได้รวมสองรูปแบบเข้าด้วยกันเพราะฉันมักจะต้องการการสนับสนุนทั้งสองโลก ในขณะที่มันเป็นความจริงที่คุณสามารถปรับแต่ง MVC มาตรฐานใด ๆController(และ / หรือพัฒนาActionResultชั้นเรียนของคุณเอง) เพื่อทำหน้าที่และประพฤติเหมือนApiControllerมันอาจเป็นเรื่องยากมากที่จะรักษาและทดสอบ: นอกเหนือจากนั้นมีวิธีควบคุมกลับActionResultผสมกับผู้อื่น การส่งคืนข้อมูลดิบ / ต่อเนื่อง / IHttpActionResultข้อมูลอาจสร้างความสับสนอย่างมากจากมุมมองของนักพัฒนาโดยเฉพาะอย่างยิ่งหากคุณไม่ได้ทำงานคนเดียวและต้องทำให้นักพัฒนาซอฟต์แวร์รายอื่น ๆ

เทคนิคที่ดีที่สุดที่ฉันใช้มาจนถึงตอนนี้เพื่อลดปัญหาดังกล่าวในแอปพลิเคชันเว็บที่ไม่ใช่คอร์ ASP.NET คือการนำเข้า (และกำหนดค่าอย่างเหมาะสม) แพ็คเกจเว็บ API ลงในแอปพลิเคชันบนเว็บที่ใช้ MVC ดังนั้นฉันจึง โลก: Controllersสำหรับ Views ApiControllersสำหรับข้อมูล

ในการทำเช่นนั้นคุณต้องทำสิ่งต่อไปนี้:

  • ติดตั้งแพคเกจดังต่อไปนี้ API เว็บโดยใช้ NuGet: และMicrosoft.AspNet.WebApi.CoreMicrosoft.AspNet.WebApi.WebHost
  • เพิ่ม ApiControllers หนึ่งรายการขึ้นไปใน/Controllers/โฟลเดอร์ของคุณ
  • เพิ่มไฟล์WebApiConfig.csต่อไปนี้ใน/App_Config/โฟลเดอร์ของคุณ:

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

ท้ายสุดคุณจะต้องลงทะเบียนคลาสข้างต้นในคลาสเริ่มต้นของคุณ( Startup.csหรือGlobal.asax.csขึ้นอยู่กับว่าคุณใช้เทมเพลตการเริ่มต้น OWIN หรือไม่)

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

วิธีการนี้ - พร้อมกับข้อดีและข้อเสีย - อธิบายเพิ่มเติมในโพสต์นี้ที่ฉันเขียนไว้ในบล็อกของฉัน


1
สิ่งที่ดี. แต่ฟังก์ชั่นนี้สร้างขึ้นด้วย vs2015 ถ้าคุณสร้างโครงการ webapi asp.net มันจะทำรหัสรหัสหม้อไอน้ำให้คุณโดยอัตโนมัติ
suomi-dev

@Darkseal คุณช่วยกรุณาอธิบายเล็กน้อยเกี่ยวกับ "มันยากมากที่จะรักษาและทดสอบ"? (ฉันได้อ่านบล็อกโพสต์ของคุณ) ฉันใช้ WebAPI2 และฉันชอบวิธีการทำงาน อย่างไรก็ตามฉันไม่สามารถเข้าใจถึง "ผลประโยชน์ที่ยิ่งใหญ่" นอกเหนือจากการมี "วิธีการทำสิ่งต่าง ๆ " การมีตัวควบคุม MVC แบบคลาสสิกที่ส่งคืนสตริงที่ "ต่อเนื่อง" ด้วยตนเองนั้นง่ายพอ การเพิ่มสวิตช์ json / xml ด้วย http ยอมรับกริยาไม่มาก ทั้งหมดที่สามารถห่อเป็นวิธีการที่ดีขอบคุณ
ValGe

2
@ValGe โปรดดู @ คำตอบ manish-jain ด้านบน โดยสรุปแล้วการControllerส่งคืนสตริง Json ที่ต่อเนื่องกันซึ่งห่ออยู่ภายในActionResultนั้นยากที่จะทดสอบและกำหนดเองApiControllerซึ่งจะถูกตั้งค่าให้ส่งคืน[Serializable]รายการโดยตรง วิธีทดสอบใด ๆ จะง่ายกว่ามากในการเขียนเนื่องจากคุณไม่จำเป็นต้องยกเลิกการทำให้เป็นอนุกรมด้วยตนเองในแต่ละครั้ง: สามารถพูดได้เหมือนกันสำหรับเกือบทุกภารกิจการรวมระบบกับ ASP.NET หรือกรอบงานอื่น ๆ Controllersดีมาก แต่ApiControllersเหมาะสำหรับงาน RESTful อย่างน้อยใน. NET Framework 4.x
Darkseal

1

ทุกวิธีใน Web API จะส่งคืนข้อมูล (JSON) โดยไม่มีการทำให้เป็นอนุกรม

อย่างไรก็ตามในการส่งคืนข้อมูล JSON ในตัวควบคุม MVC เราจะตั้งค่าประเภทผลลัพธ์การดำเนินการที่ส่งคืนเป็น JsonResult และเรียกวิธีการ Json บนวัตถุของเราเพื่อให้แน่ใจว่าบรรจุใน JSON


1

ข้อแตกต่างที่สำคัญคือ: Web API เป็นบริการสำหรับลูกค้าอุปกรณ์ใด ๆ และตัวควบคุม MVC ให้บริการลูกค้าเท่านั้น เหมือนกันเพราะมันเป็นแพลตฟอร์ม MVC


-1

มันค่อนข้างง่ายในการตัดสินใจระหว่างสอง: ถ้าคุณกำลังเขียนแอปพลิเคชันบนเว็บ / อินเทอร์เน็ต / อินทราเน็ต HTML - บางทีด้วยการโทร AJAX ที่กลับมาเป็นครั้งคราว json ที่นี่และที่นั่น - ติดกับ MVC / Controller หากคุณต้องการจัดเตรียมข้อมูลที่ขับเคลื่อนด้วย / REST-ful ส่วนต่อประสานกับระบบให้ไปที่ WebAPI คุณสามารถรวมทั้งสองอย่างเข้าด้วยกันโดยให้ ApiController ตอบสนองการโทร AJAX จากหน้า MVC โดยทั่วไปคอนโทรลเลอร์ใช้สำหรับ mvc และ api-controller ใช้สำหรับ Rest- API คุณสามารถใช้ทั้งในโปรแกรมเดียวกับที่คุณต้องการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.