89

我正在创建一个新的 MVC4 项目,研究使我相信现在通过 Web API 框架而不是控制器操作可以更好地实现从 javascript 到服务器端的通信。我对此的理解正确吗?

我假设我可以在 Web API 和 MVC 控制器之间共享我的所有属性等,所以从表面上看,这对我来说似乎并不是一个巨大的变化。

当我设置应用程序时,我喜欢将组件拆分到项目中。我的计划是有一个 MVC 项目和一个 Web API 项目。但我遇到了问题。例如,我最终得到了 2 个应用程序,单独的路由设置等。

所以我的问题是,在 MVC 应用程序中,Web API 框架应该位于同一个项目中,还是应该将 Web API 分离到自己的项目中并解决这些问题?

4

8 回答 8

111

不幸的是,你错了——我假设我可以在 web api 和 mvc 控制器之间共享我的所有属性等,所以从表面上看,这对我来说似乎并不是一个巨大的变化。

Web API 和 MVC 使用的许多概念,尽管乍一看很相似,但实际上并不兼容。例如,Web API 属性System.Web.Http.Filters.Filter和 MVC 属性是System.Web.Mvc.Filter- 并且它们是不可互换的。

这同样适用于许多其他概念 - 模型绑定(完全不同的机制)、路由(Web API 使用 HTTPRoutes 而不是路由,即使它们都在相同的底层 RouteTable 上运行)、依赖解析器(不兼容)等等 - 尽管在表面上,在实践中是非常不同的。而且,Web API 没有区域的概念。

最终,如果你想要做的只是拥有一种“新的、时尚的”方式来提供 JSON 内容——在走这条路之前要三思而后行。我当然不建议重构任何现有代码,除非您真的在考虑采用 HTTP 并以 RESTful 方式构建您的应用程序。

这完全取决于您要构建的内容。如果您正在开始一个新项目,并且您只需要提供一些 JSON 来促进您的 Web 应用程序 - 只要您愿意使用一些可能重复的代码(就像我上面提到的东西),Web API 可以很容易地托管在与 ASP.NET MVC 相同的项目。

如果您要为您的在线服务构建适当的 API - 可能由外部客户或各种设备使用 - 例如为您的移动应用程序提供燃料,我只会将 Web API 分离到一个单独的项目中。

于 2012-10-16T00:20:16.183 回答
26

IMO、安全和部署应该推动您的决定。例如,如果您的 MVC 应用程序使用表单身份验证,但您有兴趣为 API 使用基本身份验证(使用 SSL),那么单独的项目将使您的生活更轻松。如果您想在 www.example.com 托管您的站点,但将您的 API 托管为 api.example.com(相对于 www.example.com/api),单独的项目将使您的生活更轻松。如果您将您的项目和子域相应地分开,并且您打算从您的 MVC 应用程序中利用您自己的 API,您将必须弄清楚如何处理客户端调用您的 API的同源策略问题。对此的常见解决方案是利用jsonpCORS(如果可以的话最好)。

更新(2013 年 3 月 26 日):官方 CORS 支持即将到来:http ://aspnetwebstack.codeplex.com/wikipage?title=CORS%20support%20for%20ASP.NET%20Web%20API

于 2012-10-16T04:59:48.210 回答
9

经过一定程度的经验(为应用程序和 mvc 创建 API)。我主要两者都做。

我为来自其他客户端或其他设备(Android/IOS 应用程序)的 api 调用创建了一个单独的项目。原因之一是因为身份验证不同,它是基于令牌的(以保持无状态)。我不想在我的 MVC 应用程序中混合使用它。

对于我的 mvc 应用程序的 javascript/jquery api 调用,我喜欢保持简单,所以我在我的 MVC 应用程序中包含了一个 web api。我不打算对我的 javascript api 调用进行基于令牌的身份验证,因为嘿,它在同一个应用程序中。我可以[authorize]在 API 端点上使用属性,当用户未登录时,他将无法获取数据。

此外,当处理购物车并且您希望在会话中存储用户购物车(未登录时)时,如果您通过 javascript 代码添加/删除产品,您也需要在 API 中包含此内容。这肯定会让你的 API 有状态,但也会降低 MVC-API 的复杂性。

于 2016-02-12T12:51:01.403 回答
6

来自 SimpleInjector(IoC 框架)的 Steven 建议两个独立的项目:WebAPI 中的 DependencyResolver.SetResolver 和 HttpConfiguration.DependencyResolver 有什么区别

于 2013-04-19T09:14:11.640 回答
5

我最近做了几乎相同的事情:我从一个新的 MVC 4 Web 应用程序项目开始,选择 VS2012 中的 Web API 模板。

这将创建一个托管在与 MVC 相同的应用程序中的 Web API。

我想将 ApiControllers 移动到一个单独的类库项目中。这相当容易,但解决方案有点隐藏。

在 MVC 4 项目的 AssemblyInfo.cs 中添加类似的代码行

[assembly: PreApplicationStartMethod(typeof(LibraryRegistrator), "Register")]

现在你需要类 LibraryRegistrator (随意命名它)

public class LibraryRegistrator
    {
        public static void Register()
        {
            BuildManager.AddReferencedAssembly(Assembly.LoadFrom(HostingEnvironment.MapPath("~/bin/yourown.dll")));
        }
    }

在 MVC 4 项目中还添加了对 Api 库的引用。

现在您可以将 Api 控制器添加到您自己的单独类库 (yourown.dll) 中。

于 2013-06-10T12:29:24.100 回答
2

即使您的项目如此复杂以至于需要两个“前端”,那么我仍然只会考虑将 webapi 拆分为一个单独的项目作为最后的手段。您将遇到部署难题,并且新手很难理解您的解决方案的结构。更不用说路由问题了。

我的目标是将 system.web 命名空间隔离在一个“表示层”中。尽管 webapi 不是展示性的,但它仍然是应用程序界面的一部分。只要您将逻辑保留在域中而不是控制器中,就不会遇到太多问题。另外,不要忘记使用区域。

于 2012-10-15T23:53:41.117 回答
0

除了为 Web.Api 设置单独的 DLL。

只是一个建议:

  1. 创建项目
  2. Nugget WebActivatorEx
  3. 创建一个要在 app_start 上调用的类方法

    [程序集:WebActivatorEx.PostApplicationStartMethod(typeof(API.AppWebActivator),"Start")]

    [程序集:WebActivatorEx.ApplicationShutdownMethod(typeof(API.AppWebActivator), "Shutdown")]

  4. 在 Start 方法中注册一个 web.api 路由

    公共静态无效开始(){ GlobalConfiguration.Configure(WebApiConfig.Register);}

  5. 将项目引用到 Web 项目。激活启动方法。

希望这可以帮助。

于 2016-02-29T06:19:29.247 回答
0

我试图将 API 控制器拆分为一个新项目。我所做的就是创建一个新的库项目,将控制器移动到名为 API 的文件夹中。然后将库项目的引用添加到MVC项目中。

webAPI 配置保留在 MVC 项目本身中。它工作正常。

于 2016-07-19T08:19:07.090 回答