2012-10-15 141 views
76

我正在创建一个新的MVC4项目,并且研究让我相信从JavaScript到服务器端的通信现在可以通过Web API框架而不是控制器操作更好地实现。我的理解是否正确?单独项目中的MVC解决方案中的Web API

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

当我设置应用程序时,我喜欢将组件分解到项目中。我的计划是有一个MVC项目和一个Web API项目。但是我遇到了问题。例如,我已经结束了2个应用程序,分开的路由设置等等。

所以我的问题是,在MVC应用程序中,应该将Web API框架放在同一个项目中,还是应该将Web API分开纳入自己的项目并解决问题?

回答

99

不幸的是你错了 - 我假设我可以在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分离为单独的项目。

+2

+1优秀的答案。我最初认为MVC和WebAPI可能会共享一些代码,特别是在过滤器,模型绑定等情况下,但它们完全不同。 – VJAI

+0

感谢您的详细回复。我正在使用mvc控制器创建一个新的Web应用程序来为我的视图提供内容。我的计划是使用web api来处理来自我的客户端js(网站包含一些丰富的功能)通过web api到服务器的通信。一些第三方正在构建网站的组件,这些组件将被集成到网站中,并将使用Web API与服务器进行通信。所以从我阅读的内容来看,对于这样的设置,您的建议是在一个项目中使用mvc还是web api?也许有一个“api”文件夹中的web api。 – amateur

+5

是的,在这种情况下,只需在Visual Studio中启动一个新的MVC4项目,并在提示输入项目模板(第二个屏幕)时选择Web API。这将从Nuget安装Web API,并且在你描述的情况下应该是完全正确的。你得到的是单独的Web API配置文件插入Global.asax。此外,您可能希望将API控制器分为单独的文件夹(默认情况下,它们与MVC控制器一起)。最后,默认路由显然是单独配置的,不会互相干扰 –

2

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

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

+1

我想要单独项目的主要原因是API不是真正的前端。这是中层。 – lordcheeto

+4

“新手难以理解”并不是选择一种方法的理由。尽可能保持简单,当然,但复杂的需求通常需要复杂的解决方案。我们应该培养新手以理解和编写智能代码,而不是编写愚蠢的代码来迎合新手。 – Dan

25

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

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

+0

我试图围绕将Web API与我的MVC应用程序集成的决定,或将它作为一个单独的项目来解决问题。我能够成功地将Web API HelloWorld应用程序部署到我的虚拟主机上的子域。从这个单独的项目中,我可能会使用我的MVC Web应用程序中的模型并在该单独的项目中调用代码。似乎沿着这个单独项目的路线可能会更容易,但您认为我可以用这种方法解决哪些问题? –

+2

个人而言,我不会将您的视图模型用作您的API的DTO。我希望这个决定会在你的视图模型和API签名出现分歧时引起你的痛苦。 SoC(http://en.wikipedia.org/wiki/Separation_of_concerns)非常重要。 –

+0

@DavidPeden你建议为WebAPI创建一个新的独立项目。真的吗?另一方面,我将为WebAPI创建一个新的单独项目(我目前在我的应用程序中有一个UI层(MVC)和数据层(类库),所以我也使用DI,但我想知道我是否可以使用在新创建的WebAPI项目的数据层中使用相同的实体,存储库,接口和抽象类,我唯一​​需要做的就是创建WebAPI控制器?还是我也创建了所有这些(实体,存储库,接口和摘要类)再次为WebAPI?请任何帮助吗? –

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)中。

7

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

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

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

此外,在处理购物车时,如果您希望在会话中存储用户购物车(而未登录),则需要在API中包含此功能,以及通过JavaScript代码添加/删除产品。这将确保您的API有状态,但也会降低MVC-API的复杂性。

+4

那么@Dimi,这是一个无用的编辑来获得一些选票......我怎样才能拒绝这些? – CularBytes

+0

做你想做的事情,我不是通过投票来编辑,而是为了获得最好的外观 我假设。前进。 –

+3

@CularBytes您不能拒绝编辑,但您可以再次编辑它并回滚更改。这需要2000人以下的同行评审过程,但您有足够的代表立即执行此操作。我同意这个修改没有增加任何价值,并且已经为你回滚了。 – Dan

0

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

只是一个建议:

  1. 创建项目
  2. 掘金WebActivatorEx
  3. 创造出一个类的方法在app_start

    [组件被称为:WebActivatorEx.PostApplicationStartMethod(typeof运算(API。 AppWebActivator), “开始”)]

    [组件:WebActivatorEx.ApplicationShutdownMethod(吨ypeof(API.AppWebActivator), “关断”)]

  4. 注册Start方法

    公共静态无效启动(){ GlobalConfiguration.Configure(WebApiConfig.Register)内的web.api路线; }

  5. 参考项目的Web项目。激活启动方法。

希望这会有所帮助。

0

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

的配置的WebAPI留在MVC项目本身。它工作正常。

相关问题