在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. C#泛型简单应用

    最近老板要在app里开展金融模块了,产品一下就丢丢丢二三十个表单下来,怎么办,赶紧写代码,有20多个表单要提交呢,得建20多个表.等等,好像这些表单很相似,公司信息,个人信息,可是还有部分不同信息怎么 ...

  2. org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: file [/Users/lonecloud/tomcat/apache-tomcat-7.0.70 2/webapps/myproject/WEB-INF/classes/cn/lone

    解决这个报错的解决办法: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidat ...

  3. Spring实现无需注解实现自动注入

    xml配置 过程:设置自动装配的包-->使用include-filter过滤type选择为regex为正则表达式-->expression是表达是式也就是限制条件 <?xml ver ...

  4. Ubuntu14.04上安装Composer

    1,查看机子上有没有安装php 2,下载Composer的安装包 3,安装Composer 4,设置Composer全局可访问

  5. hihoCoder 树结构判定(并查集)

    思路:树满足两个条件: 1.顶点数等于边数加一 2.所有的顶点在一个联通块 那么直接dfs或者并查集就可以了. AC代码 #include <stdio.h> #include<st ...

  6. hdu5296 01字典树

    根据二进制建一棵01字典树,每个节点的答案等于左节点0的个数 * 右节点1的个数 * 2,遍历整棵树就能得到答案. AC代码: #include<cstdio> using namespa ...

  7. UVA-10954 贪心+优先队列

    贪心策略:每次选取最小的两个数相加,将和作为新的数加入序列,再从里面取两个最小的数...直到只剩下一个数.优先队列正好对付这题. PS :以前在学校OJ做过几乎一毛一样的这题 AC代码: #inclu ...

  8. eclipse Maven配置

    ①下载:http://maven.apache.org/download.cgi ②解压至:F:\Study\apache-maven-3.5.2 ③配置环境变量 变量名:M2_HOME 变量值:F: ...

  9. linux mysql重启命令

    1.通过rpm包安装的MySQL 1 2 service mysqld restart /etc/inint.d/mysqld start 2.从源码包安装的MySQL 1 2 3 4 // Linu ...

  10. 网络基础tcp/ip协议三

    数据链路层:(位于网络层与物理层之间) 数据链路层的功能: 数据链路的建立,维护. 帧包装,帧传输,帧同步. 帧的差错恢复. 流量的控制. 以太网:(工作在数据链路层) CSMA/CD(带冲突检测的载 ...