【问题标题】:Difference between ApiController and Controller in ASP.NET MVCASP.NET MVC中ApiController和Controller的区别
【发布时间】:2012-03-18 16:38:54
【问题描述】:

我一直在使用 ASP.NET MVC 4 beta,现在我看到了两种类型的控制器:ApiControllerController

在什么情况下我可以选择特定的控制器时,我有点困惑。

例如:如果我想返回一个视图,那么我必须使用ApiController 还是普通的Controller?我知道 WCF Web API 现在已与 MVC 集成。

由于现在我们可以同时使用这两个控制器,请有人指出在哪些情况下使用相应的控制器。

【问题讨论】:

标签: asp.net-mvc asp.net-web-api


【解决方案1】:

使用 Controller 渲染您的普通视图。 ApiController 动作只返回序列化后发送给客户端的数据。

here is the link

引用:

注意如果您使用过 ASP.NET MVC,那么您已经熟悉控制器。它们在 Web API 中的工作方式类似,但 Web API 中的控制器派生自 ApiController 类而不是 Controller 类。您会注意到的第一个主要区别是 Web API 控制器上的操作不返回视图,而是返回数据。

ApiController 专门用于返回数据。例如,他们负责将数据透明地序列化为客户端请求的格式。此外,它们默认遵循不同的路由方案(例如:将 URL 映射到操作),按照约定提供 REST-ful API。

您可能可以使用 Controller 而不是 ApiController 和 some(?) 手动编码来做任何事情。最后,这两个控制器都建立在 ASP.NET 基础之上。但如今,拥有一个 REST-ful API 是如此普遍的要求,以至于创建 WebAPI 是为了简化此类 API 的实现。

在两者之间做出选择相当简单:如果您正在编写基于 HTML 的 web/internet/intranet 应用程序 - 可能偶尔 AJAX 调用会在这里和那里返回 json - 坚持使用 MVC/Controller。如果您想为系统提供数据驱动/REST-ful 接口,请使用 WebAPI。当然,您可以将两者结合起来,让 ApiController 满足来自 MVC 页面的 AJAX 调用。

举一个真实世界的例子:我目前正在使用一个 ERP 系统,该系统为其实体提供 REST-ful API。对于这个 API,WebAPI 将是一个不错的选择。同时,ERP 系统提供了一个高度 AJAX 化的 Web 应用程序,您可以使用它来为 REST-ful API 创建查询。 Web 应用程序本身可以实现为 MVC 应用程序,利用 WebAPI 获取元数据等。

【讨论】:

  • 注意:由于您的数据将通过网络发送,它将如何格式化? ApiController 返回的数据格式由内容协商决定,GlobalConfiguration.Configuration.Formatters... 链接:blogs.msdn.com/b/kiranchalla/archive/2012/02/25/…
  • 说 Web API 是网站、移动设备等的通用平台是否正确?我们可以使用类库而不是 Web API 吗?
  • 感谢@TimLovell-Smith 的注释,因为对我而言,Andre 没有回答这个问题:作为 Controller 也可以返回数据,它没有解释为什么 ApiController 存在并且有用。跨度>
  • @JYL 我扩充了我的答案以提供更详细的信息。
  • 当你说“按惯例提供 REST-ful API”时,我真的不明白。它如何提供 REST-ful API?它不取决于您从 API 返回的数据吗?控制器中没有任何东西可以强制(甚至促进)API 为 REST-ful。
【解决方案2】:

您更愿意编写和维护哪个?

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

【讨论】:

  • 这很好,但 ApiController 不仅仅是 JSON 序列化。它还负责查看请求并返回 XML(如果这是接受类型)。
  • 如果你使用asp.net core,都是从Controller类派生出来的。
  • 这似乎是老例子,现在我们不用担心ApiController 只是: Controller 工作,你能添加新的dot net core Controller 例子吗
  • @AshishKamble,现在使用 ControllerBase 代替 ApiController。
  • 老实说,我宁愿拥有Json() 版本。它更清晰,更明确。我不喜欢在试图弄清楚我的代码将如何响应请求时使用大量黑魔法。
【解决方案3】:

我喜欢 ASP.NET Core 的 MVC6 将这两种模式合二为一,因为我经常需要同时支持这两种模式。虽然您确实可以调整任何标准 MVC Controller(和/或开发自己的 ActionResult 类)以像 ApiController 一样操作和表现,但它可能很难维护和测试:在顶部也就是说,从开发人员的角度来看,将返回 ActionResultControllers 方法与返回原始/序列化/IHttpActionResult 数据的其他方法混合在一起可能会非常令人困惑,特别是如果您不是一个人工作并且需要携带其他开发人员可以加快使用这种混合方法的速度。

到目前为止,为了最大限度地减少 ASP.NET 非核心 Web 应用程序中的该问题,我采用的最佳技术是将 Web API 包导入(并正确配置)到基于 MVC 的 Web 应用程序中,这样我就可以拥有两全其美:Controllers 用于查看,ApiControllers 用于数据。

为此,您需要执行以下操作:

  • 使用 NuGet 安装以下 Web API 包:Microsoft.AspNet.WebApi.CoreMicrosoft.AspNet.WebApi.WebHost
  • 将一个或多个 ApiController 添加到您的 /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 类(Startup.csGlobal.asax.cs,取决于您是否使用 OWIN Startup 模板)。

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

我在博客上写的this post 进一步解释了这种方法及其优缺点。

【讨论】:

  • 好东西。但是这个功能已经内置在 vs2015 中了。如果您创建 webapi asp.net 项目,它将自动为您完成所有样板代码。
  • @Darkseal 您能否详细说明“它可能很难维护和测试”? (我已阅读您的博文)我使用过 WebAPI2,我喜欢它的工作方式。但是,除了拥有“常见的做事方式”之外,我无法弄清楚“真正的大好处”。让经典的 MVC 控制器返回“手动”序列化的字符串很容易。添加带有 http Accept 动词的 json/xml 开关并不需要太多。所有这些都可以封装到一个不错的实用方法中。谢谢。
  • @ValGe ,请参阅上面的@manish-jain 答案。简而言之,Controller 返回包裹在 ActionResult 中的 Json 序列化字符串肯定比 ApiController 更难测试和维护,ApiController 可以设置为直接返回 [Serializable] 项目列表。任何测试方法都会更容易编写,因为您不必每次都手动反序列化:几乎所有与 ASP.NET 或其他框架的系统集成任务都可以这样说。 Controllers 很棒,但 ApiControllers 更适合 RESTful 任务,至少在 .NET Framework 4.x 中是这样
【解决方案4】:

Web API 中的每个方法都将返回数据 (JSON),无需序列化。

但是,为了在 MVC 控制器中返回 JSON 数据,我们将返回的 Action Result 类型设置为 JsonResult 并在我们的对象上调用 Json 方法以确保它被封装在 JSON 中。

【讨论】:

    【解决方案5】:

    主要区别在于:Web API 是针对任何客户端、任何设备的服务,而 MVC 控制器仅服务于它的客户端。一样,因为它是 MVC 平台。

    【讨论】:

      【解决方案6】:

      快速简短的回答

      如果你想返回一个视图,你应该在“控制器”中。

      普通控制器 - ASP.NET MVC:如果您在 ASP.net Web 应用程序中,则处理普通的“控制器”。您可以创建 Controller-Actions 并返回 Views()。

      ApiController 控制器:您在开发 ASP.net REST API 时创建 ApiController。您不能返回视图(尽管您可以将 HTML 的 Json/Data 作为字符串返回)。这些 api 被视为后端,它们的函数被调用以返回数据而不是视图

      请不要忘记将此标记为答案,小心

      More Details here

      【讨论】:

      • 没有理由将此标记为答案,哈哈!
      【解决方案7】:

      在 Asp.net Core 3+ 版本中

      Controller:如果还想返回任何与 IActionResult & Data 相关的内容,请选择 Controllercontroller

      ApiController:在 API 控制器中用作属性/符号。继承ControllerBase类

      ControllerBase:如果想返回数据只去ControllerBase类

      【讨论】:

        【解决方案8】:

        如果您在最新的框架 4.7.2 中创建一个新的 Web 应用程序,您将默认配置它们,并且可以在该框架上构建您的应用程序

        【讨论】:

          猜你喜欢
          • 2011-09-19
          • 1970-01-01
          • 2020-11-25
          • 2010-12-25
          • 1970-01-01
          • 1970-01-01
          • 2020-06-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多