Nancy in .NET Core學習筆記 - 路由

前文中,我介紹了Nancy的來源和優勢,並建立了一個簡單的Nancy應用,在網頁中輸出了一個"Hello World",本篇我來總結一下Nancy中的路由html

Nancy中的路由的定義

Nancy中的路由是定義在每一個Module的構造函數中的。
爲了建立一個路由,你須要定義以下4個部分正則表達式

  • Http請求的方法(Method)
  • 路由模板(Pattern)
  • 處理對應路由模板請求的響應方法(Action)
  • 條件約束(Condition)

前篇的代碼爲例瀏覽器

public class HelloModule : NancyModule
    {
        public HelloModule()
        {
            Get("/", p => "Hello World");
        }
    }

當前構造中定義了的一個路由框架

  • 它的Http請求方法是GET
  • 它的路由模板是"/", 即網站根目錄
  • 它的響應結果是輸出一個"Hello World"
  • 這裏它沒有指定任何的條件約束

Nancy中支持的Http請求方法(Http Method)

Nancy中支持DELETE, GET, HEAD, OPTIONS, POST, PUTPATCHide

Nancy中的路由模板(Pattern)

下面咱們介紹一下Nancy中默認提供的幾種路由片斷和約束條件。函數

Nancy中的幾種路由片斷

Nancy中默認支持一下幾種路由片斷。測試

純文字片斷(Literal Segment)

例: /products/cocacola網站

public class ProductModule : NancyModule
    {
        public ProductModule()
        {
            Get("/products/cocacola", p => "Coca Cola");
        }
    }

含變量的片斷(Capture Segment)

Nancy中Get方法的第二個參數是一個Func委託, Func<dynamic, object>, 該委託的指向方法的第一個參數是dynamic類型的變量, 咱們能夠從該變量上獲取Url中的可變參數的值。ui

例: /products/{productName}3d

public class ProductModule : NancyModule
    {
        public ProductModule()
        {
            Get("/products/{productName}", p => p.productName);
        }
    }

含可空變量的片斷(Capture Segment - Optional)

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);
        }
    }

正則片斷(RegEx Segment)

Nancy的路由模板中也可使用正則表達式。

例:/products/(? [\d]{2,})

public class ProductModule : NancyModule
    {
        public ProductModule()
        {
            Get(@"/products/(?<productId>[\d]{2,})", p => "Your product id is " + p.productId);
        }
    }

這個正則的意思是隻容許2位數以上的整數。

貪婪片斷(Greedy Segment)

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中的條件約束(Condition)

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中的視圖引擎。

附源代碼

相關文章
相關標籤/搜索