前文中,我介绍了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中的视图引擎。