在上一篇的.NET輕量級MVC框架:Nancy入門教程(一)——初識Nancy中,簡單介紹了Nancy,並寫了一個Hello,world。看到大家的評論,都在問Nancy的優勢在哪裡?和微軟的MVC比有什麼不同,哪個更好?Nancy是否可以脫離IIS等等,那麼今天就拿MVC和Nancy做個簡單的對比吧!首先說一點,我對MVC研究並不深入,如有沒說到或說錯的地方,還請大家補充和糾正。
下面糾正一個問題,Nancy官網並沒有明確的說Nancy是一個MVC框架,官方的定義是:Nancy是一個用於構建基於HTTP 的Web服務的框架。我題目中所寫的輕量級MVC框架有些不妥之處,但是可以讓大家快速的對Nancy有個大致的瞭解。不過,說實話,Nancy和asp.net在一起,實在是太像MVC了。
今天主要講理論的東西,不寫程式碼,文章中所提到的配置,只是為了幫助理解,詳細配置和操作內容還請參考官方幫助文件。
1、Hosting Nancy with asp.net
方案一:整站都使用Nancy
在ASP.NET中,Nancy通過設定web.config,使用HTTP handler來處理請求。如果你在Visual Studio中使用了Nancy的模板來建立,就會自動生成webconfig配置,否則就要新增如下配置到webconfig中:
<system.web> <compilation debug="true" targetFramework="4.0" /> <httpHandlers> <add verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*"/> </httpHandlers> </system.web> <system.webServer> <modules runAllManagedModulesForAllRequests="true"/> <validation validateIntegratedModeConfiguration="false"/> <handlers> <add name="Nancy" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*"/> </handlers> </system.webServer>
並且還要確定你新增了Nancy和Nancy.Hosting.Aspnet 兩個dll的引用。
方案二:網站中一部分使用Nancy
除了使用Nancy搭建整個網站,我們還可以在已存在的網站中使用Nancy來處理某些特定路徑的請求。例如我們要處理nancypath下面的所有請求,我們只需要修改上面的配置NancyHttpRequestHandler的path為path="nancypath/*",並且你也要在專案中新增指定路徑的資料夾,並在資料夾內放入如下Web.config:
<?xml version="1.0"?> <configuration> <system.web> <httpHandlers> <add verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*"/> </httpHandlers> </system.web> </configuration>
除此之外,再修改webconfig中的<location>節點配置。
方案三:在MVC中使用Nancy
是的,你沒有看錯,Nancy和MVC一起使用,如果要在MVC中使用Nancy,需要修改Global.asax.cs檔案,新增如下內容:
routes.IgnoreRoute("nancy/{*pathInfo}");
這個時候,所有訪問nancy目錄的請求,就都會被Nancy處理了,接下來,我們就可以這樣寫程式碼了,例如:
public class Home : NancyModule { public Home() { Get["/nancy/products"] = x => "The products!"; } }
這部分詳細內容參考:https://github.com/NancyFx/Nancy/wiki/Hosting-Nancy-with-asp.net
2.Hosting Nancy with wcf
如果你想搭建一個輕量級的HTTP服務而又不想使用IIS,Nancy是一個很好的選擇,你可以按照下面的操作來實現:
首先,安裝Nancy.Hosting.Wcf,Nugget程式碼如下:
PM> Install-Package Nancy.Hosting.Wcf
然後,編寫程式碼,如下:
var host = new WebServiceHost(new NancyWcfGenericService(), new Uri("http://localhost:1234/base/")); host.AddServiceEndpoint(typeof (NancyWcfGenericService), new WebHttpBinding(), ""); host.Open(); // Nancy will now handle requests to http://localhost:1234/base/
然後,Nancy就會偵聽本地的1234埠,處理HTTP請求。
這部分詳細內容參考:https://github.com/NancyFx/Nancy/wiki/Hosting-Nancy-with-wcf
除此之外,Nancy還有以下Host方式:
Hosting-nancy-with-azure 參考:https://github.com/NancyFx/Nancy/wiki/Hosting-nancy-with-azure
Hosting-nancy-with-owin 參考:https://github.com/NancyFx/Nancy/wiki/Hosting-nancy-with-owin
Hosting-Nancy-with-Umbraco 參考:https://github.com/NancyFx/Nancy/wiki/Hosting-Nancy-with-Umbraco
Hosting-Nancy-with-Nginx-on-Ubuntu 參考:https://github.com/NancyFx/Nancy/wiki/Hosting-Nancy-with-Nginx-on-Ubuntu
Hosting-Nancy-with-FastCgi 參考:https://github.com/NancyFx/Nancy/wiki/Hosting-Nancy-with-FastCgi
Self-Hosting-Nancy 參考:https://github.com/NancyFx/Nancy/wiki/Self-Hosting-Nancy
1、Nancy中的路由機制
在上一篇的博文中,我們都知道Nancy中的所有路由都定義在module中的構造方法中,我們上次定義了一個無參路由,如下:
public class HelloModule : NancyModule { public HelloModule() { Get["/"] = parameters => "Hello World"; } }
Nancy中有參路由可以這樣定義:
public class ProductsModule : NancyModule { public ProductsModule() { Get["/products/{id}"] = _ => { //do something }; } }
或者定義成非同步的,如下:
public class ProductsModule : NancyModule { public ProductsModule() { Get["/products/{id}", runAsync: true] = async (_, token) => { //do something long and tedious }; } }
Nancy中支援的method有:DELETE
, GET
, HEAD
, OPTIONS
, POST
, PUT
and PATCH
.
當然,Nancy中還支援路由引數約束,例如我們要求引數必須為int型別,我們可以這樣定義:
Get["/intConstraint/{value:int}"] = _ => "Value " + _.value + " is an integer.";
除了int型別,Nancy還支援以下型別的約束:
感覺還不夠?Nancy還提供了自定義引數約束,比如我們要求引數是一個email,我們可以先定義如下類:
public class EmailRouteSegmentConstraint : RouteSegmentConstraintBase<string> { public override string Name { get { return "email"; } } protected override bool TryMatch(string constraint, string segment, out string matchedValue) { if (segment.Contains("@")) { matchedValue = segment; return true; } matchedValue = null; return false; } }
然後,定義路由如下:
Get["/profile/{value:email}"] = _ => "Value " + _.value + " is an e-mail address.";
下面是Nancy中路由常用的幾種寫法:
當然,Nancy的路由機制非常強大、非常靈活,那麼當一個地址可以匹配多個路由時,Nancy會選擇哪一個呢?其實,Nancy中有一套路由的權重機制來解決路由衝突,這個到後面說路由的時候會詳細說的。
2、MVC中的路由機制
我們都知道MVC中的路由配置都在 Global.asax.cs中,當一個ASP.NET MVC應用程式第一次執行時, Application_Start()方法被呼叫。這個方法,又呼叫RegisterRoutes()方法,RegisterRoutes()方法建立了路由表。
MVC中的預設路由如下:
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // 路由名稱 "{controller}/{action}/{id}", // 帶有引數的 URL new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 引數預設值 (UrlParameter.Optional-可選的意思) ); }
NVC中無參路由定義如下:
routes.MapRoute ( "Home", "{controller}/{action}/{id}" );
MVC中帶名稱空間的路由定義如下:
routes.MapRoute( "AdminControllers", // 路由名稱 "{controller}/{id}-{action}", // 帶有引數的 URL new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // 引數預設值 new string[] { "Admin.Controllers" }//名稱空間 );
MVC中帶約束的路由定義如下:
routes.MapRoute( "RuleControllers", "{controller}/{action}-{Year}-{Month}-{Day}}", new { controller = "Home", action = "Index", Year = "2014", Month = "12", Day = "08" }, new { Year = @"^\d{4}", Month = @"\d{2}" } //4位數 2位數 );
MVC全域性路由:
routes.MapRoute( "All", // 路由名稱 "{*Vauler}", // 帶有引數的 URL new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 引數預設值 );
綜上所述,MVC和Nancy的路由機制從功能上來說不相上下,MVC有的Nancy也有。不過,相比之下,Nancy中的路由更加簡單、靈活,畢竟MVC中的路由對於新手來說不是那麼容易掌握的。
當然,檢視這塊大家還是比較關注的。下面簡單對比MVC和Nancy所支援的檢視:
MVC | Nancy | |
WebForm | 支援 | 支援 |
Razor | 支援 | 支援 |
這裡我們看到MVC和nancy都支援WebForm和Razor檢視。並且,Nancy在Razor檢視中也支援Model的繫結和部分檢視,在Nancy中的部分檢視中,也可以使用Modle繫結。
雖然微軟剛剛宣佈開源不久,但是在這之前,asp.net就可以通過Mono實現跨平臺了。當然MVC和Nancy也可以通過Mono來實現跨平臺。
到這裡,對在上一篇中所提到的問題,相信大家心中已經有答案了吧~~
作者:雲霏霏
QQ交流群:243633526
部落格地址:http://www.cnblogs.com/yunfeifei/
宣告:本部落格原創文字只代表本人工作中在某一時間內總結的觀點或結論,與本人所在單位沒有直接利益關係。非商業,未授權,貼子請以現狀保留,轉載時必須保留此段宣告,且在文章頁面明顯位置給出原文連線。
如果大家感覺我的博文對大家有幫助,請推薦支援一把,給我寫作的動力。