在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. Python自动化--语言基础2--运算符、格式化输出、条件语句、循环语句、列表、元组

    运算符包括:算术运算符.比较运算符.赋值运算符.逻辑运算符.成员运算符.身份运算符 算术运算符 %   取模(余数) //  取相除的整数部分 /   (5/2=2.5) 比较运算符 ==  等于 ! ...

  2. Android App 压力测试方法(Monkey)

    一.为什么要开展压力测试 a.提高产品的稳定性:b.提高产品的留存率 二.什么时候开展压力测试 a.首轮功能测试通过后:b.下班后的夜间进行 三.7个基础知识(理论部分) 3.1 手动测试场景与自动测 ...

  3. 微信开发系列——微信订阅号前端开发利器:WeUI

    前言:年前的两个星期,学习了下微信公众号的开发.后端基本能够基于盛派的第三方sdk能搞定大部分事宜.剩下的就是前端了,关于手机端的浏览器的兼容性,一直是博主的一块心病,因为博主一直专注于bootstr ...

  4. Duilib第一步(I)-简介与环境搭建

    Primus gradus et cognoscetis veritatem et veritas liberabit vos.  --Johannes 8:32 Introduction Duili ...

  5. iOS实现从服务器请求json数据并转化成NSDictionary

    NSURL *url = [NSURL URLWithString:URL]; NSURLRequest *request = [NSURLRequest requestWithURL:url cac ...

  6. 浅谈 maxMemory , totalMemory , freeMemory 和 OOM 与 native Heap

    作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...

  7. Tensorflow中实现BN为什么需要加入这个额外依赖?见CS231N作业源码

    batch normalization in tensorflow requires this extra dependency 为什么加上这两句? extra_update_ops = tf.get ...

  8. 计蒜客 取数游戏 博弈+dp

    题目链接 取数游戏 思路:dp(x, y)表示先手在区间[x, y]能取得的最大分数.当先手取完,就轮到后手去,后手一定会选择当前能令他得到最大分数的策略,其实当先手在[x, y]区间两端取走一个数, ...

  9. Supervisor使用说明

    Supervisor是一个 Python 开发的 client/server 系统,可以管理和监控类 UNIX 操作系统上面的进程.它可以同时启动,关闭多个进程,使用起来特别的方便. 1.组成部分 s ...

  10. 经典卷积神经网络(LeNet、AlexNet、VGG、GoogleNet、ResNet)的实现(MXNet版本)

    卷积神经网络(Convolutional Neural Network, CNN)是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现. 其中 文章 详解卷 ...