Разница между ApiController и Controller в ASP.NET MVC

343

Я играл с ASP.NET MVC 4 beta и теперь вижу два типа контроллеров: ApiControllerи Controller.

Меня немного смущает, в каких ситуациях я могу выбрать тот или иной контроллер.

Например: если я хочу вернуть представление, то я должен использовать ApiControllerили обычный Controller? Я знаю, что веб-API WCF теперь интегрирован с MVC.

Поскольку теперь мы можем использовать оба контроллера, может кто-нибудь указать, в каких ситуациях использовать соответствующий контроллер.

VJAI
источник
23
Важно: ASPNET Ядро имеет «слиты» ApiControllerи Controllerпоэтому , если вы используете более новый .NET вам не нужно беспокоиться о ApiController больше - docs.microsoft.com/en-us/aspnet/core/tutorials/first-web- API
Simon_Weaver
2
Рад, что они сделали! Я предсказал это давно назад путем prideparrot.com/blog/archive/2012/10/asp_net_mvc_vs_webapi
VJAI

Ответы:

356

Используйте контроллер для рендеринга ваших обычных представлений. Действие ApiController возвращает только те данные, которые сериализованы и отправлены клиенту.

вот ссылка

Quote:

Примечание. Если вы работали с ASP.NET MVC, то вы уже знакомы с контроллерами. Они работают аналогично в Web API, но контроллеры в Web API наследуются от класса ApiController, а не от класса Controller. Первое существенное отличие, которое вы заметите, заключается в том, что действия на контроллерах Web API не возвращают представления, они возвращают данные.

ApiControllers специализируются на возврате данных. Например, они заботятся о прозрачной сериализации данных в формат, запрошенный клиентом. Кроме того, они следуют другой схеме маршрутизации по умолчанию (как в: сопоставление URL-адресов с действиями), предоставляя API REST-ful по соглашению.

Вы могли бы сделать что-нибудь, используя Controller вместо ApiController с некоторым (?) Ручным кодированием. В конце оба контроллера основываются на фундаменте ASP.NET. Но наличие REST-ful API является настолько распространенным требованием сегодня, что WebAPI был создан для упрощения реализации такого API.

Выбор между ними довольно прост: если вы пишете приложение на основе HTML для веб / интернета / интранета - возможно, из-за случайного вызова AJAX, возвращающего json тут и там - придерживайтесь MVC / Controller. Если вы хотите предоставить управляемый данными / REST-ful интерфейс для системы, используйте WebAPI. Конечно, вы можете комбинировать и то, и другое, имея вызовы AJAX от ApiController со страницы MVC.

Чтобы привести пример из реальной жизни: в настоящее время я работаю с системой ERP, которая предоставляет API-интерфейс REST своим организациям. Для этого API WebAPI был бы хорошим кандидатом. В то же время система ERP предоставляет веб-приложение с высокой степенью AJAX, которое можно использовать для создания запросов к API REST-ful. Само веб-приложение может быть реализовано как приложение MVC, использующее WebAPI для извлечения метаданных и т. Д.

Андре Локер
источник
9
Примечание: поскольку ваши данные будут отправлены по сети, как они будут отформатированы? То, как данные, которые возвращает ApiController, форматируется, определяется согласованием содержимого, и ссылка GlobalConfiguration.Configuration.Formatters
Тим Ловелл-Смит
1
Правильно ли говорить, что Web API - это общая платформа для веб-сайтов, мобильных устройств и т. Д.? и мы могли бы использовать библиотеку классов вместо веб-API?
Имад Алазани,
Спасибо @ TimLovell-Smith за вашу заметку, потому что для меня Андре не отвечает на вопрос: поскольку контроллер также может возвращать данные, он не объясняет, почему ApiController существует и является полезным.
JYL
2
@JYL Я дополнил свой ответ, чтобы предоставить более подробную информацию.
Андре Локер
2
Я не совсем понял, когда вы сказали «предоставление REST-ful API по соглашению» . Как это обеспечивает REST-ful API? Разве это не зависит от того, какие данные вы возвращаете из API? В контроллере нет ничего, что заставляло бы (или даже облегчало) API быть REST-полным.
Наваз
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, если это тип принятия.
Джейк Алмер
10
Если вы используете ядро ​​asp.net, все они являются производными от Controllerкласса.
Tân
2
Это , кажется , старые примеры, теперь не нужно беспокоиться о ApiControllerтолько : Controllerработе, вы можете добавить новый точечный чистый базовый пример контроллера тоже
Ashish Kamble
@AshishKamble, вместо ApiController теперь используется ControllerBase.
Владимир Шиянов
Честно говоря, я бы предпочел Json()версию. Это понятнее и понятнее. Я не люблю кучу черной магии, пытаясь выяснить, как мой код будет отвечать на запрос.
Jez
27

Мне нравится тот факт, что ASP.NET Core MVC6 объединил два шаблона в один, потому что мне часто нужно поддерживать оба мира. Хотя это правда, что вы можете настроить любой стандартный MVC Controller(и / или разработать свои собственные ActionResultклассы) так, чтобы он действовал и вел себя так же, как и его ApiController, его очень сложно поддерживать и тестировать: кроме того, методы Controllers возвращают ActionResultсмешанные с другими Возвращение необработанных / сериализованных / IHttpActionResultданных может быть очень запутанным с точки зрения разработчика, особенно если вы работаете не в одиночку и вам необходимо ускорить работу других разработчиков с помощью этого гибридного подхода.

Лучший способ, который я до сих пор использовал, чтобы минимизировать эту проблему в неосновных веб-приложениях ASP.NET, - это импортировать (и правильно настроить) пакет веб-API в веб-приложение на основе MVC, чтобы я мог использовать оба миры: Controllersдля представлений, ApiControllersдля данных.

Для этого вам необходимо сделать следующее:

  • Установите следующие пакеты веб-API с помощью NuGet: Microsoft.AspNet.WebApi.Coreи Microsoft.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);
    // ...
}

Этот подход - вместе с его плюсами и минусами - более подробно объясняется в этом посте, который я написал в своем блоге.

Darkseal
источник
1
хорошая вещь. но эта функциональность уже встроена в vs2015. если вы создадите проект webapi asp.net, он автоматически сделает весь код котельной плиты за вас.
Суоми-Дев
@Darkseal, не могли бы вы рассказать немного о том, что «это может быть очень сложно поддерживать и тестировать»? (Я прочитал ваше сообщение в блоге) Я использовал WebAPI2, и мне нравится, как он работает. Однако я не могу понять "действительно большую выгоду", кроме того, что это "обычный способ делать вещи". Классические контроллеры MVC, возвращающие «вручную» сериализованные строки, достаточно просты. Добавление переключателя json / xml с глаголом http Accept не займет много времени. Все это можно обернуть в полезный метод. Спасибо.
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 Controller обслуживает только своего клиента. То же самое, потому что это платформа MVC.

АНЖИР - КОДЭКСПРЕССИЯ
источник
-1

Выбор между ними довольно прост: если вы пишете приложение на основе HTML для веб / интернета / интранета - возможно, из-за случайного вызова AJAX, возвращающего json тут и там - придерживайтесь MVC / Controller. Если вы хотите предоставить управляемый данными / REST-ful интерфейс для системы, используйте WebAPI. Конечно, вы можете комбинировать и то, и другое, имея вызовы AJAX от ApiController со страницы MVC. В основном, контроллер используется для mvc, а api-контроллер - для Rest-API, вы можете использовать оба в одной программе, как вам нужно


источник