在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. 使用docker搭建wordpress

    前言 去年在学习docker,在看完菜鸟教程和第一本docker书后,一直想实战用一下这个技术,多用用才能熟能生巧,真正体验它的利弊.正好傅老板用docker搭完了wordpress,我也就手痒跟着搭 ...

  2. Angular4.0用命令行创建组件服务出错

    之前使用cnpm创建的angular4.0项目,由于cnpm下载的node_modules资源经常会有部分缺失,所以在用命令行创建模板.服务的时候会报错: Error: ELOOP: too many ...

  3. 安装 LightGBM 包的过程

    conda install cmake conda install gcc git clone --recursive https://github.com/Microsoft/LightGBM ; ...

  4. 在jdbc中使用properites文件进行使用

    首先先在源代码中创建一个properites文件 db_url=jdbc\:mysql\://localhost\:3306/db_friend db_user=root db_password= d ...

  5. Ubuntu14.04+Nginx+MySql+PHP环境配置

    http://www.cnblogs.com/gophper/p/4793711.html

  6. BZOJ4554 - [TJOI2016&HEOI2016]游戏

    原题链接 Description 给出一个的地图,地图上有空地.软石头和硬石头.求在这张地图上最多能放上多少个炸弹能使得任意两个炸弹之间不会互相炸到.炸弹能炸到的范围是该炸弹所在的一行和一列,炸弹的威 ...

  7. BZOJ3224/洛谷P3391 - 普通平衡树(Splay)

    BZOJ链接 洛谷链接 题意简述 模板题啦~ 代码 //普通平衡树(Splay) #include <cstdio> int const N=1e5+10; int rt,ndCnt; i ...

  8. ANTD mobile源码分析 -- popover

    最近的开发中要用到很多的各式各样的组件.但是发现ant design mobile(后面简称ANTDM)里很多的资源.于是就分析一下,学习学习. ANTDM直接使用了typescript,没有用ES2 ...

  9. Mapreuduce实现网络数据包的清洗工作

    处理后的数据可直接放到hive或者mapreduce程序来统计网络数据流的信息,比如当前实现的是比较简单的http的Get请求的统计 第一个mapreduce:将时间.十六进制包头信息提取出来,并放在 ...

  10. Centos小白命令

    centos在登录界面无法输入密码 Centos安装flash插件 Centos挂载windows ntfs分区 Centos搭建Eclipse C/C++环境 windows下的txt文件在cent ...