Sự khác biệt giữa ApiContoder và Trình điều khiển trong ASP.NET MVC


343

Tôi đã chơi xung quanh với ASP.NET MVC 4 beta và bây giờ tôi thấy hai loại bộ điều khiển: ApiControllerController.

Tôi hơi bối rối về những tình huống tôi có thể chọn một bộ điều khiển cụ thể.

Ví dụ: Nếu tôi muốn trả về một chế độ xem thì tôi sẽ sử dụng ApiControllerhay thông thường Controller? Tôi biết rằng API Web WCF hiện được tích hợp với MVC.

Vì bây giờ chúng ta có thể sử dụng cả hai bộ điều khiển, ai đó có thể vui lòng chỉ ra tình huống nào sẽ xảy ra cho bộ điều khiển tương ứng.


23
Quan trọng: ASPNET Core đã 'hợp nhất' ApiControllerControllervì vậy nếu bạn đang sử dụng .NET mới hơn, bạn không cần phải lo lắng về ApiContoder nữa - docs.microsoft.com/en-us/aspnet/core/tutorials/first-web- api
Simon_Weaver

2
Vui vì họ đã làm! Tôi đã dự đoán điều này từ lâu bằng cách prideparrot.com/blog/archive/2012/10/asp_net_mvc_vs_webapi
VJAI

Câu trả lời:


356

Sử dụng Bộ điều khiển để hiển thị các chế độ xem bình thường của bạn. Hành động ApiControll chỉ trả về dữ liệu được tuần tự hóa và gửi đến máy khách.

đây là đường dẫn

Trích dẫn:

Lưu ý Nếu bạn đã làm việc với ASP.NET MVC, thì bạn đã quen thuộc với các bộ điều khiển. Chúng hoạt động tương tự trong API Web, nhưng các bộ điều khiển trong API Web xuất phát từ lớp ApiContoder thay vì lớp Trình điều khiển. Sự khác biệt lớn đầu tiên bạn sẽ nhận thấy là các hành động trên bộ điều khiển API Web không trả về lượt xem, chúng trả về dữ liệu.

ApiControllers chuyên trả về dữ liệu. Ví dụ, họ đảm nhiệm việc tuần tự hóa dữ liệu thành định dạng theo yêu cầu của khách hàng. Ngoài ra, họ theo một sơ đồ định tuyến khác theo mặc định (như: ánh xạ URL thành hành động), cung cấp API REST-Ful theo quy ước.

Bạn có thể có thể làm bất cứ điều gì bằng cách sử dụng Bộ điều khiển thay vì ApiContoder với mã hóa thủ công (?). Cuối cùng, cả hai bộ điều khiển đều xây dựng trên nền tảng ASP.NET. Nhưng việc có API REST-Ful là một yêu cầu phổ biến hiện nay là WebAPI được tạo ra để đơn giản hóa việc triển khai API như vậy.

Việc quyết định giữa hai bên khá đơn giản: nếu bạn đang viết một ứng dụng web / internet / mạng nội bộ dựa trên HTML - có thể với cuộc gọi AJAX thỉnh thoảng trả về json ở đây và ở đó - gắn với MVC / Trình điều khiển. Nếu bạn muốn cung cấp giao diện điều khiển dữ liệu / REST-Ful cho hệ thống, hãy truy cập WebAPI. Tất nhiên, bạn có thể kết hợp cả hai, có ApiControll phục vụ các cuộc gọi AJAX từ một trang MVC.

Để đưa ra một ví dụ trong thế giới thực: Tôi hiện đang làm việc với một hệ thống ERP cung cấp API REST-Ful cho các thực thể của nó. Đối với API này, WebAPI sẽ là một ứng cử viên tốt. Đồng thời, hệ thống ERP cung cấp ứng dụng web mang tính AJAX cao mà bạn có thể sử dụng để tạo truy vấn cho API REST-Ful. Bản thân ứng dụng web có thể được triển khai như một ứng dụng MVC, sử dụng WebAPI để tìm nạp dữ liệu meta, v.v.


9
Lưu ý: vì dữ liệu của bạn sẽ được gửi qua dây, nó sẽ được định dạng như thế nào? Các dữ liệu như vậy một ApiController lợi nhuận được định dạng được xác định thông qua thương lượng nội dung, và GlobalConfiguration.Configuration.Formatters ... liên kết: blogs.msdn.com/b/kiranchalla/archive/2012/02/25/...
Tim Lovell-Smith

1
Có đúng không khi nói rằng API Web là một Nền tảng phổ biến cho trang web, thiết bị di động, v.v.? và chúng ta có thể sử dụng Thư viện lớp thay vì API Web?
Imad Alazani

Cảm ơn @ TimLovell-Smith vì lưu ý của bạn, vì đối với tôi, Andre không trả lời câu hỏi: vì Bộ điều khiển cũng có thể trả về dữ liệu, điều đó không giải thích tại sao ApiControll tồn tại và hữu ích.
JYL

2
@JYL Tôi đã tăng câu trả lời của mình để cung cấp thông tin chi tiết hơn.
Andre Loker

2
Tôi thực sự không hiểu khi bạn nói "cung cấp API REST-Ful theo quy ước" . Làm thế nào để nó cung cấp API REST-Ful? Nó không phụ thuộc vào dữ liệu bạn trả về từ API? Không có gì trong bộ điều khiển buộc API (hoặc thậm chí tạo điều kiện) API trở thành REST-Ful.
Nawaz

192

Mà bạn muốn viết và duy trì?

ASP.NET MVC

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

API web ASP.NET

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

6
Đó là một điểm tốt nhưng ApiControll không chỉ là tuần tự hóa JSON. Nó cũng quan tâm đến việc xem xét yêu cầu và trả về XML nếu đó là loại chấp nhận.
Jake Almer

10
Nếu bạn sử dụng lõi asp.net, tất cả chúng đều có nguồn gốc từ Controllerlớp.
Tân

2
Đây có vẻ là ví dụ cũ, Bây giờ chúng tôi không cần phải lo lắng về việc ApiControllerchỉ : Controllerhoạt động, bạn có thể thêm ví dụ Bộ điều khiển lõi chấm mới không
Ashish Kamble

@AshishKamble, Thay vì ApiControll, Trình điều khiển hiện được sử dụng.
Vladimir Shiyanov

Thành thật mà nói, tôi muốn có Json()phiên bản. Nó rõ ràng và rõ ràng hơn. Tôi không thích một khối ma thuật đen khi cố gắng tìm ra cách mã của tôi sẽ đáp ứng với một yêu cầu.
Jez

27

Tôi thích thực tế là MVC6 của ASP.NET Core đã hợp nhất hai mẫu thành một vì tôi thường cần hỗ trợ cả hai thế giới. Mặc dù đúng là bạn có thể điều chỉnh bất kỳ MVC tiêu chuẩn nào Controller(và / hoặc phát triển các ActionResultlớp của riêng bạn ) để hành động và hành xử giống như một ApiController, nhưng rất khó để duy trì và kiểm tra: trên hết, có các phương thức Bộ điều khiển quay lại ActionResulttrộn lẫn với các lớp khác trả về dữ liệu thô / tuần tự / IHttpActionResultdữ liệu có thể rất khó hiểu từ góc độ nhà phát triển, đặc biệt nếu bạn không làm việc một mình và cần đưa các nhà phát triển khác tăng tốc với phương pháp lai đó.

Kỹ thuật tốt nhất mà tôi đã có từ trước đến nay để giảm thiểu vấn đề đó trong các ứng dụng web không phải lõi của ASP.NET là nhập (và cấu hình đúng) gói API Web vào Ứng dụng web dựa trên MVC, vì vậy tôi có thể có cả hai tốt nhất thế giới: Controllerscho Lượt xem, ApiControllerscho dữ liệu.

Để làm điều đó, bạn cần làm như sau:

  • Cài đặt các gói API Web sau bằng NuGet: Microsoft.AspNet.WebApi.CoreMicrosoft.AspNet.WebApi.WebHost.
  • Thêm một hoặc nhiều ApiControllers vào /Controllers/ thư mục .
  • Thêm tệp WebApiConfig.cs sau vào /App_Config/thư mục của bạn :

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

Cuối cùng, bạn sẽ cần phải đăng ký lớp trên vào lớp Khởi động của mình ( Startup.cshoặc Global.asax.cs, tùy thuộc vào việc bạn có sử dụng mẫu Khởi động OWIN hay không).

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

Toàn cầu.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);
    // ...
}

Cách tiếp cận này - cùng với ưu và nhược điểm của nó - được giải thích thêm trong bài đăng này tôi đã viết trên blog của mình.


1
điều tốt. nhưng chức năng này đã được tích hợp sẵn với vs2015. nếu bạn tạo dự án webapi asp.net, nó sẽ tự động làm tất cả mã tấm nồi hơi cho bạn.
suomi-dev

@Darkseal bạn có thể vui lòng giải thích một chút về "có thể rất khó để duy trì và kiểm tra" không? (Tôi đã đọc bài đăng trên blog của bạn) Tôi đã sử dụng WebAPI2 và tôi thích cách nó hoạt động. Tuy nhiên tôi không thể tìm ra "lợi ích lớn thực sự" bên cạnh việc có "cách làm việc chung". Có các bộ điều khiển MVC cổ điển trả về các chuỗi nối tiếp "thủ công" là đủ dễ dàng. Thêm một chuyển đổi json / xml với http Động từ chấp nhận không mất nhiều. Tất cả những gì có thể được gói vào một phương thức tiện ích tốt đẹp. Cảm ơn.
ValGe

2
@ValGe, xem @ manish-jain trả lời ở trên. Tóm lại, một chuỗi Controllertrả về Json được nối tiếp trong một chuỗi ActionResultchắc chắn khó kiểm tra và bảo đảm hơn một chuỗi ApiControllercó thể được đặt để trả về trực tiếp danh sách các [Serializable]mục. Bất kỳ phương pháp kiểm tra nào cũng sẽ dễ viết hơn nhiều, bởi vì bạn sẽ không phải hủy tuần tự hóa thủ công mỗi lần: có thể nói tương tự đối với gần như mọi tác vụ tích hợp hệ thống với ASP.NET hoặc các khung công tác khác. Controllerslà tuyệt vời, nhưng ApiControllersphù hợp hơn cho các nhiệm vụ RESTful, ít nhất là trong .NET Framework 4.x
Darkseal 7/07/19

1

Mọi phương thức trong API Web sẽ trả về dữ liệu (JSON) mà không cần tuần tự hóa.

Tuy nhiên, để trả về Dữ liệu JSON trong bộ điều khiển MVC, chúng tôi sẽ đặt loại Kết quả hành động được trả về thành JsonResult và gọi phương thức Json trên đối tượng của chúng tôi để đảm bảo nó được đóng gói trong JSON.


1

Sự khác biệt chính là: API Web là một dịch vụ cho mọi khách hàng, mọi thiết bị và Bộ điều khiển MVC chỉ phục vụ khách hàng của nó. Tương tự vì nó là nền tảng MVC.


-1

Việc quyết định giữa hai bên khá đơn giản: nếu bạn đang viết một ứng dụng web / internet / mạng nội bộ dựa trên HTML - có thể với cuộc gọi AJAX thỉnh thoảng trả về json ở đây và ở đó - gắn với MVC / Trình điều khiển. Nếu bạn muốn cung cấp giao diện điều khiển dữ liệu / REST-Ful cho hệ thống, hãy truy cập WebAPI. Tất nhiên, bạn có thể kết hợp cả hai, có ApiControll phục vụ các cuộc gọi AJAX từ một trang MVC. Về cơ bản bộ điều khiển được sử dụng cho mvc và bộ điều khiển api được sử dụng cho Rest-API, bạn có thể sử dụng cả hai trong cùng một chương trình khi bạn cần

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.