在Nancy中,最为神奇的莫过于路由了,定义路由模块是构成Nancy应用的骨架。在Nancy中定义路由,和在 ASP.NET MVC那些类似的框架中有着非常大的区别。

以 ASP.NET MVC 为例,通常情况需要创建一个控制类。多数情况下,这个类提供了路由的约定。通过定义您的控制器类名和该类中的方法的名称,就能定义了该代码所处理的“路由”

请看下面的例子:

using System;
using System.Linq;
using System.Web.Mvc;
namespace Intranet.WebUi.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
}

这段从标准ASP.NET MVC 应用程序摘录的代码定义了Home路由下的Index节点,用于将Http请求路由到这段代码 ,请求地址应该是这样的   /home/index 。 如果使用Nancy,就会有些不一样了。

首先,在Nancy应用中,继承NancyModule基类,才能定义路由。第二,不是每个路由都需要定义在一个单独的类中(如 MVC示例),可以在模块类的构造构造函数中定义路由,使用Rest动词定义路由类型。

当然这可能导致过于庞大的构造函数,但是也有很多方式处理这个问题。

在往下看之前,我们需要先了解一些概念......

如果您习惯于看到从 web 浏览器的触发的web 请求,你可能不知道,在它之下是相当复杂的协议。如果你从事于 web相关的开发工作,很可能听说过称为 HTTP 协议。HTTP通过使用一系列的动词来表示客户端希望服务器采取某些行动。

采用Nancy,也无需了解太多HTTP动词的细节。实际上创建一个REST 风格的应用,用到下面的Rest动词就好:

  • GET
  • POST
  • PUT
  • DELETE

GET,顾名思义,用来检索数据从服务;同样,删除是习惯请求数据被删除。PUT和POST可能经常会造成混乱。遵循规范, PUT意思是“整体替换指定的”,而POST用于“在现有基础上添加”。许多开发人员创建基于 rest 风格的应用程序,也不过就是使用GET和POST。

这方面Nancy走的更进一步,不同于大多数其他 web 为基础的框架,你可以定义自己的动词。在某种意义上,允许您创建您自己的基于HTTP的特定领域的语言。让我们深入剖析的Nancy路由模块,看看是如何工作的。

    我们的第一个Nancy路由模块

看下面的代码

using Nancy;
namespace nancybook.modules
{
public class BaseRoutes : NancyModule
{
public BaseRoutes()
{
Get[@"/"] = _ => Response.AsFile("index.html", "text/html");
}
}
}

作为一个Nancy项目,这是例子再简单不过了。

这个只有十一行的代码,监听所有向应用程序的"/"根路径的请求,返回"Content"文件一个名为“index.html”HTTP页面。

Content 文件夹是Nancy查询文件的默认文件夹,在下一张关于视图Views的章节,我们会涉及更多,但现在,只是确保项目有一个文件夹被称为Content,所有的 HTML 文件都放置于此。

撇开通常命名空间和类的代码部分 ,只有两点是这个Nancy路由模块添加的:继承了NancyModule ,在构造函数中使用GET规则。

GET规则意味着这将响应使用 GET 动词的 HTTP 调用,代码将执行响应根路径的 GET 请求。

如何你要扩展这个模块处理 GET,POST,PUT,和DELETE,你需要这么处理:

using Nancy;
namespace nancybook.modules
{
public class BaseRoutes : NancyModule
{
public BaseRoutes()
{
Get[@"/"] = _ => Response.AsFile("index.html", "text/html");
Put[@"/"] = _ => Response.AsFile("index.html", "text/html");
Post[@"/"] = _ => Response.AsFile("index.html", "text/html");
Delete[@"/"] = _ => Response.AsFile("index.html", "text/html");
}
}
}

模块监听的路径或路由需要放置到动词后面的方括号中。所以,举个例子,你可以像下面是的修改:

using Nancy;
namespace nancybook.modules25
{
public class BaseRoutes : NancyModule
{
public BaseRoutes()
{
Get[@"/allpeople"] = _ => Response.AsFile("index.html", "text/html");
Put[@"/allpeople"] = _ => Response.AsFile("index.html", "text/html");
Post[@"/newperson"] = _ => Response.AsFile("index.html",
"text/html");
Delete[@"/singleperson"] = _ => Response.AsFile("index.html",
"text/html");
}
}
}

为了演示的目的,每个请求都返回一个静态网页。在真是环境中,每个实际的请求你可能都需要根据实际的功能需求编写合适的处理代码。本章接下来对这个话题进行更多的介绍。

你也可以为你的模块编写通用的路径。试想下面的例子:

using Nancy;
namespace nancybook.modules
{
public class BaseRoutes : NancyModule
{
public BaseRoutes()
{
Get[@"/single"] = _ => Response.AsFile("index.html", "text/html");
Put[@"/single"] = _ => Response.AsFile("index.html", "text/html");
Post[@"/new"] = _ => Response.AsFile("index.html", "text/html");
Delete[@"/single"] = _ => Response.AsFile("index.html", "text/html");
}
}
}

很快你就会发现代码变得难以阅读。 另外,如果你想用一致的命名方法来编写你的API,重用single 和new 来处理应用程序中的其他资源。

再一次,Nancy展现了其简单的处理方式,仅仅通过在模块类中重载父类NancyModule的构造函数并传递根目录路径。

namespace nancybook.modules
{
public class BaseRoutes : NancyModule
{
public BaseRoutes() : base("/people")
{
Get[@"/single"] = _ => Response.AsFile("index.html", "text/html");
Put[@"/single"] = _ => Response.AsFile("index.html", "text/html");
Post[@"/new"] = _ => Response.AsFile("index.html", "text/html");
Delete[@"/single"] = _ => Response.AsFile("index.html", "text/html");
}
}
}

通过添加父类构造函数的调用,瞬间已经更改了您的模块将响应的所有 Url:

  • GET /single
  • PUT /single
  • POST /new
  • DELETE /single

转变为:

  • GET /people/single
  • PUT /people/single
  • POST /people/new
  • DELETE /people/single

加上一点创造性思维和一些聪明的软件开发点子,你甚至可以在很多地方重用同一个控制器。

在我们继续之前,还是要提一个关于“Rest动词”的警告。一些托管环境(包括ASP.NET/IIS)默认是不支持一些常用的动词。

在前面的示例中,如果运行在 IIS 中,你会发现PUT和DELETE导致服务器返回以下错误: 503   方法不被允许。

这并不是Nancy的问题,而是,IIS 只允许两个最常见动词(GET 和 POST)。如果你参考下Stack Overflow的文章,这个问题不难解决。

    路由参数

正如其他的web工具包,您的路由模块也可以接收各种各样的数据。这些数据包括简单的 URL 参数,如记录的 ID 或博客分类号,也有通过POST或PUT传递的复杂对象。

在这一章,我们会讲解基于路由的简单数据,以后的章节再介绍复杂的对象。

你已经看到了,为响应给定的请求,在Nancy路由模块中修改URL非常简单。但如果需要在URL中传递记录ID该怎么办?

using Nancy;
namespace nancybook.modules
{
public class BaseRoutes : NancyModule
{
public BaseRoutes() : base("/people")
{
Get[@"/{id}"] = parameters =>
{
var myRecordId = parameters.id;
return Response.AsFile("Pages/index.html", "text/html");
};
}
}
}

如果你想限定参数的类型,请看下面示例:

using Nancy;
namespace nancybook.modules
{
public class BaseRoutes : NancyModule
{
public BaseRoutes() : base("/people")
{
Get[@"/{id:int}"] = parameters =>
{
var myRecordId = parameters.id;
return Response.AsFile("Pages/index.html", "text/html");
};
}
}
}

注意在路由参数上增加了int限制;任何尝试传递非整数参数都会导致404未找到的错误。Nancy定义许多这些的限制,基本上都绑在.NET 基元类型:

  • long
  • decimal
  • guid
  • bool
  • datetime

你可以在URL中添加很多的参数,如下:

using Nancy;
namespace nancybook.modules
{
public class BaseRoutes : NancyModule
{
public BaseRoutes() : base("/people")
{
Get[@"/person/{age:int}/{surname}/categories/{category}/{city}"] =
parameters =>
{
return Response.AsFile("Pages/index.html", "text/html");
};
}
}
}

    总结

在本章中,您已经学到了如何使用路由模块创建应用程序的骨架,了解到了Nancy与ASP.NET MVC在路由上定义的不同。你已经看到了如何定义路由路径,不再通过类的名字控制路由定义,了解了如何使用动词和在URL中传递参数。在下一章中,我们会看看视图引擎,看看如何返回一些其他东西,不只是普通的 HTML 文档。

NancyFX 第五章 Nancy 路由的更多相关文章

  1. NancyFX 第四章 Nancy快速上手 (使用Nancy模板)

    在我们进一步深入学习Nancy之前,我们先快速的了解下Visual Studio下的Nancy模板. 采用Nancy模板,创建一个Nancy项目就像我们创建MVC应用或winForm应用一样简单,只需 ...

  2. PJSUA2开发文档--第五章 帐户(号)Accounts

    第五章 帐户(号) 帐户提供正在使用该应用程序的用户的身份(或身份).一个帐户有一个与之相关的SIP统一资源标识符(URI).在SIP术语中,该URI用作该人的记录地址( Address of Rec ...

  3. 《NodeJS开发指南》第五章微博实例开发总结

    所有文章搬运自我的个人主页:sheilasun.me <NodeJS开发指南>这本书用来NodeJS入门真是太好了,而且书的附录部分还讲到了闭包.this等JavaScript常用特性.第 ...

  4. 2019寒假训练营第三次作业part1-网络空间安全概论第五章

    第五章 网络攻防技术 5.1 网路信息收集技术--网络踩点 黑客入侵系统之前,需要了解目标系统可能存在的: 管理上的安全缺陷和漏洞 网络协议安全缺陷与漏洞 系统安全缺陷与漏洞 黑客实施入侵过程中,需要 ...

  5. 第五章、 Linux 常用網路指令

    http://linux.vbird.org/linux_server/0140networkcommand.php     第五章. Linux 常用網路指令 切換解析度為 800x600 最近更新 ...

  6. 【WPF学习】第十三章 理解路由事件

    每个.NET开发人员都熟悉“事件”的思想——当有意义的事情发生时,由对象(如WPF元素)发送的用于通知代码的消息.WPF通过事件路由(event routing)的概念增强了.NET事件模型.事件路由 ...

  7. 【WPF学习】第十四章 事件路由

    由上一章可知,WPF中的许多控件都是内容控件,而内容控件可包含任何类型以及大量的嵌套内容.例如,可构建包含图形的按钮,创建混合了文本和图片内容的标签,或者为了实现滚动或折叠的显示效果而在特定容器中放置 ...

  8. 《Django By Example》第五章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者@ucag注:大家好,我是新来的翻译, ...

  9. 《Entity Framework 6 Recipes》中文翻译系列 (22) -----第五章 加载实体和导航属性之延迟加载

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第五章 加载实体和导航属性 实体框架提供了非常棒的建模环境,它允许开发人员可视化地使 ...

随机推荐

  1. solr6.6教程-从mysql数据库中导入数据(三)

    整理多半天的solr6.6,终于算是把solr6.6中配置数据库弄出来了,网上的文章千篇一律,各说个的,没有一篇统一覆盖solr6.6版本配置的 帖子,本章节我会把配置的一些注意事项一一列举,由于时间 ...

  2. Eclipse搭建Maven项目之准备工作

    Maven是优秀的Java项目对象模型解决方案,意为知识的积累(意地绪文),Maven可以方便的解决Java项目包依赖问题,通过配置pom.xml引入依赖,并自动引入其他依赖. 操作系统版本:wind ...

  3. python中 字符 字典 列表之间的转换

    1 字典 转 字符 定义一个字典:dict = {'name': 'python', 'age': 7}字典转字符 可以使用str强制转换 如: str(dict) 此时dict的类型就是字符型了 2 ...

  4. 安装VMware Workstation提示the msi failed的解决办法

    有朋友安装VMware Workstation时出现报错,提示the msi failed等信息,原来他以前安装过绿色版.优化版的VM,但删掉后重装VM就会有这样的报错提示,如果你也遇到了相同的困扰, ...

  5. 分布式mysql中间件(mycat)

    1.   MyCAT概述 1.1 背景 随着传统的数据库技术日趋成熟.计算机网络技术的飞速发展和应用范围的扩充,数据库应用已经普遍建立于计算机网络之上.这时集中式数据库系统表现出它的不足: (1)集中 ...

  6. linux权限归属及特殊权限设置

    访问权限:读取:允许查看内容 -read写入:允许修改内容 -write可执行:允许运行和切换 -excute(以上三点rwx共同决定最终权限)归属关系:所有者:拥有此文件/目录的用户 -user所属 ...

  7. html、text、val、attr、prop区别。this.value和$(this).val()区别以及return用法

    html(): html() 方法返回或设置被选元素的内容 (inner HTML). 当使用该方法读取多个值时,它会返回第一个匹配元素的内容. 当使用该方法设置一个值时,它会覆盖所有匹配元素的内容. ...

  8. R︱Rstudio 1.0版本尝鲜(R notebook、下载链接、sparkR、代码时间测试profile)

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 2016年11月1日,RStudio 1.0版 ...

  9. PCI9054 学习小结

    PCI的基本协议这里就不介绍了,因为一般的芯片协议都是集成好的,我只需要大体了解就行,不需要做芯片,我感觉就不需要太了解协议. 这里讲解是基于PLX 的9054(9052)芯片为基础的,本人只是入门, ...

  10. CPLD/FPGA厂商概述 .

    随着可编程逻辑器件应用的日益广泛,许多IC制造厂家涉足PLD/FPGA领域.目前世界上有十几家生产CPLD/FPGA的公司,最大的三家是:ALTERA,XILINX,Lattice,其中ALTERA和 ...