ASP.NET MVC中的ApiController和Controller之间的区别


343

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

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

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

从现在开始,我们可以同时使用这两种控制器,请有人指出对应控制器的情况。


23
重要提示:ASPNET Core已“合并” ApiControllerController因此,如果您使用的是较新的.NET,则无需再担心ApiController-docs.microsoft.com/zh-cn/aspnet/core/tutorials/first-web- api
Simon_Weaver

2
VJAI

Answers:


356

使用Controller渲染普通视图。ApiController操作仅返回已序列化并发送到客户端的数据。

链接在这里

引用:

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

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

您可以使用控制器而不是带有some(?)手动编码的ApiController来执行任何操作。最后,两个控制器都基于ASP.NET基础。但是,如今,拥有REST-ful API已成为一种普遍要求,因此创建WebAPI就是为了简化此类API的实现。

在这两者之间做出决定是相当简单的:如果您要编写基于HTML的Web /互联网/内联网应用程序-可能偶尔会在此不停地返回json的AJAX调用-坚持使用MVC / Controller。如果要为系统提供数据驱动/基于REST的接口,请使用WebAPI。当然,您可以将两者结合起来,让ApiController满足来自MVC页面的AJAX调用。

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


9
注意:由于您的数据将通过网络发送,因此将如何格式化?数据的方式,一个ApiController回报格式化是由内容协商确定,并GlobalConfiguration.Configuration.Formatters ...链接:blogs.msdn.com/b/kiranchalla/archive/2012/02/25/...
蒂姆·洛弗尔-史密斯

1
说Web API是用于网站,移动设备等的通用平台是正确的吗?并且我们可以使用类库而不是Web API?
Imad Alazani 2013年

感谢@ TimLovell-Smith的注释,因为对我来说,Andre没有回答这个问题:由于Controller也可以返回数据,因此并不能解释ApiController存在的原因并且很有用。
JYL 2013年

2
@JYL我扩大了答案,以提供更多详细信息。
Andre Loker 2013年

2
当您说“按惯例提供REST-ful API”时,我不太了解。它如何提供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(如果这是接受类型)。
杰克·阿尔默

10
如果使用asp.net core,则所有这些都派生自Controller类。
2016年

2
这似乎是老的例子,现在我们不需要操心ApiController只是: Controller工作,你可以添加新的点网的核心控制器的例子太多
阿希什Kamble

@AshishKamble,而不是ApiController,现在使用ControllerBase。
弗拉基米尔·希亚诺夫

老实说,我宁愿有这个Json()版本。它更加清晰明了。在尝试弄清楚我的代码如何响应请求时,我不喜欢黑魔法。
耶斯,

27

我喜欢ASP.NET Core的MVC6将两种模式合并为一个事实,因为我经常需要同时支持这两种情况。的确,您可以调整任何标准MVC Controller(和/或开发自己的ActionResult类)来像一样操作和行为ApiController,但很难维护和测试:最重要的是,让Controllers方法返回的方法ActionResult与其他方法混合使用IHttpActionResult从开发人员的角度来看,返回原始/序列化的/ 数据可能会造成很大的混乱,尤其是如果您不是一个人工作并且需要让其他开发人员加快使用该混合方法的速度时。

到目前为止,我为使ASP.NET非核心Web应用程序中的问题最小化的最佳技术是将Web API包导入(并正确配置)到基于MVC的Web应用程序中,因此我可以兼得两者worlds:Controllers用于视图,ApiControllers用于数据。

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

  • 使用NuGet安装以下Web API软件包: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类(Startup.csGlobal.asax.cs,取决于您是否使用OWIN Startup模板)。

启动文件

 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控制器返回“手动”序列化字符串很容易。添加带有http Accept动词的json / xml开关并不需要太多。所有这些都可以包装成一个不错的实用程序方法。
ValGe

2
@ValGe,请参见上面的@ manish-jain答案。简而言之,Controller返回一个包裹在中的Json序列化字符串ActionResult肯定比测试ApiController可以设置直接返回[Serializable]项目列表的字符串难得多。任何测试方法都更容易编写,因为您不必每次都手动进行反序列化:几乎可以将任何与ASP.NET或其他框架进行的系统集成任务都说成反序列化。Controllers很棒,但ApiControllers更适合RESTful任务,至少在.NET Framework 4.x中
Darkseal

1

Web API中的每个方法都将返回数据(JSON),而不进行序列化。

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


1

主要区别在于:Web API是针对任何客户端,任何设备的服务,而MVC Controller仅为其客户端提供服务。相同,因为它是MVC平台。


-1

在这两者之间做出决定是相当简单的:如果您要编写基于HTML的Web /互联网/内联网应用程序-可能偶尔会在此不停地返回json的AJAX调用-坚持使用MVC / Controller。如果要为系统提供数据驱动/基于REST的接口,请使用WebAPI。当然,您可以将两者结合起来,让ApiController满足来自MVC页面的AJAX调用。基本上,控制器用于mvc,而api-controller用于Rest- API,您可以根据需要在同一程序中使用两者

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.