2012-10-15 146 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項目本身。它工作正常。

相關問題