前文中,我介紹了Nancy的來源和優勢,並建立了一個簡單的Nancy應用,在網頁中輸出了一個"Hello World",本篇我來總結一下Nancy中的路由html
Nancy中的路由是定義在每一個Module的構造函數中的。
爲了建立一個路由,你須要定義以下4個部分正則表達式
以前篇的代碼爲例瀏覽器
public class HelloModule : NancyModule { public HelloModule() { Get("/", p => "Hello World"); } }
當前構造中定義了的一個路由框架
Nancy中支持DELETE
, GET
, HEAD
, OPTIONS
, POST
, PUT
和PATCH
ide
下面咱們介紹一下Nancy中默認提供的幾種路由片斷和約束條件。函數
Nancy中默認支持一下幾種路由片斷。測試
例: /products/cocacola網站
public class ProductModule : NancyModule { public ProductModule() { Get("/products/cocacola", p => "Coca Cola"); } }
Nancy中Get方法的第二個參數是一個Func委託, Func<dynamic, object>
, 該委託的指向方法的第一個參數是dynamic
類型的變量, 咱們能夠從該變量上獲取Url中的可變參數的值。ui
例: /products/{productName}3d
public class ProductModule : NancyModule { public ProductModule() { Get("/products/{productName}", p => p.productName); } }
Nancy中的Url參數也支持可空類型, 只須要在參數後面加一個問號。
例:/products/{productName?}
public class ProductModule : NancyModule { public ProductModule() { Get("/products/{productName?}", p => p.productName == null ? "Missing the name" : p.productName); } }
Nancy中對於可空類型的參數也能夠設置默認值, 默認值能夠放在問號的後面。
例:/products/{productName?defaultName}
public class ProductModule : NancyModule { public ProductModule() { Get("/products/{productName?defaultName}", p => p.productName); } }
Nancy的路由模板中也可使用正則表達式。
例:/products/(?
[\d]{2,})
public class ProductModule : NancyModule { public ProductModule() { Get(@"/products/(?<productId>[\d]{2,})", p => "Your product id is " + p.productId); } }
這個正則的意思是隻容許2位數以上的整數。
Nancy中能夠在變量尾部追加一個星號,表示匹配從當前位置到Url結尾的全部字符串。
例:/products/{productName*}
public class ProductModule : NancyModule { public ProductModule() { Get("/products/{productName*}", p => p.productName); } }
如今咱們把星號去掉看一下區別。
例:/products/{productName}
不能匹配到任何路由模板。
在ASP.NET MVC中咱們會使用MapRoute方法定義的路由模板,當有請求進入的時候,MVC Handler會根據咱們定義的路由模板順序來依次匹配, 若是匹配成功就會進入對應的Action方法處理請求。
那麼在Nancy這種無配置的框架中如何肯定模板的匹配順序呢?
在Nancy中,對於默認提供的幾種路由片斷類型,Nancy都提供了一個模板分數(Pattern Scoring),模板分數越高的越優先匹配。
Nancy中幾種基本模板類型的分數
模板 | 分數 |
---|---|
純文字片斷(Literal Segment) | 10000 |
含變量的片斷(Capture Segment) | 1000 |
含可空變量的片斷(Capture Segment - Optional) | 1000 |
正則片斷(RegEx Segment) | 1000 |
貪婪正則片斷(Greedy RegEx Segment) | 100 |
多變量片斷(Multiple Captures Segment) | 100 |
貪婪片斷(Greedy Segment) | 0 |
例:當前有2個路由模板"/products/{productName}"和"/products/coffee",咱們請求Url爲/products/coffee時,結果以下
public class ProductModule : NancyModule { public ProductModule() { Get("/products/{productName}", p => p.productName); Get("/products/coffee", p => "Hello Coffee."); } }
這裏是由於純文字片斷的優先級別比含變量的片斷高,因此優先處理了當前請求。
Nancy還能夠在路由模板中對參數類型進行約束。約束的格式是"{變量名: 約束類型}"。
例: "/products/{productId:int}"
public class ProductModule : NancyModule { public ProductModule() { Get("/products/{productId:int}", p => "Product id is " + p.productId); } }
當約束條件匹配時,請求成功。
當約束條件不匹配時,請求失敗。
Nancy中提供以下的常規約束類型。
約束類型 | 解釋說明 |
---|---|
int | 只容許Int32的數字 |
long | 只容許Int64的數字 |
decimal | 只容許小數 |
guid | 只容許Guid |
bool | 只容許true/false |
alpha | 只容許字母 |
datetime | 只容許時間 |
datetime(format) | 只容許特定格式時間 |
min(mininum) | 容許的最小整數值 |
max(maxinum) | 容許的最大整數值 |
range(mininum, maxinum) | 容許的整數值範圍 |
minlength(length) | 容許的字符串最小長度 |
maxlength(length) | 容許的字符串最大長度 |
length(length) | 容許的字符串長度範圍 |
version | 只容許版本號,例1.0.0 |
Nancy中能夠經過繼承RouteSegmentConstraintBase
和ParameterizedRouteSegmentConstraintBase
來自定義約束條件。
RouteSegmentConstraintBase
- 不帶參數約束條件的積累
ParameterizedRouteSegmentConstraintBase- 帶參數約束條件的基類
下面咱們本身建立一個email約束。
首先咱們建立一個EmailRouteSegmentConstraint
類,並繼承RouteSegmentConstraintBase
類,其代碼以下
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; } }
其中TryMatch方法表示嘗試判斷參數是否匹配,若是返回true就是匹配成功,false就是匹配失敗。Name屬性表示了當前約束的名稱。
咱們建立一個新的StaffModule
類,其代碼以下
public class StaffModule : NancyModule { public StaffModule() { Get("/staff/{email:email}", p => "Your email is " + p.email); } }
下面咱們啓動項目,在瀏覽器中輸入/staff/lamondlu@qq.com,請求被正確處理。
這時若是咱們在瀏覽器中輸入/staff/lamondlu, 系統會返回404。
Nancy中還能夠實現針對請求的一些條件約束。
例如:當提交的Form中包含email字段,且email字段的值爲lamondlu@qq.com時才處理當前請求。
public class StaffModule : NancyModule { public StaffModule() { Post("/staff", p => "Submited", p => p.Request.Form.email == "lamondlu@qq.com"); } }
這裏我加入了第三個參數condition, condition是一個Func<NancyContext, bool>
類型的委託, 從NancyContext中咱們能夠得到請求的全部信息。這裏我從請求的Form中讀取的email字段,若是email字段的值是lamondlu@qq.com, Nancy將返回一個Submited文本。
下面咱們使用Postman來測試一下。
首先咱們在Form中不加入任何字段,請求結果以下。
而後咱們在Form中加入email字段,且值爲lamondlu@qq.com, 請求結果以下。
請求被正確處理了。
以上就是Nancy路由部分的所有內容,有興趣的同窗能夠加個人QQ:309728709一塊兒研究, 下一次我將分享Nancy中的視圖引擎。