.NET轻量级MVC框架:Nancy入门教程(二)——Nancy和MVC的简单对比
在上一篇的.NET轻量级MVC框架:Nancy入门教程(一)——初识Nancy中,简单介绍了Nancy,并写了一个Hello,world。看到大家的评论,都在问Nancy的优势在哪里?和微软的MVC比有什么不同,哪个更好?Nancy是否可以脱离IIS等等,那么今天就拿MVC和Nancy做个简单的对比吧!首先说一点,我对MVC研究并不深入,如有没说到或说错的地方,还请大家补充和纠正。
下面纠正一个问题,Nancy官网并没有明确的说Nancy是一个MVC框架,官方的定义是:Nancy是一个用于构建基于HTTP 的Web服务的框架。我题目中所写的轻量级MVC框架有些不妥之处,但是可以让大家快速的对Nancy有个大致的了解。不过,说实话,Nancy和asp.net在一起,实在是太像MVC了。
今天主要讲理论的东西,不写代码,文章中所提到的配置,只是为了帮助理解,详细配置和操作内容还请参考官方帮助文档。
1、Hosting Nancy with asp.net
方案一:整站都使用Nancy
在ASP.NET中,Nancy通过设置web.config,使用HTTP handler来处理请求。如果你在Visual Studio中使用了Nancy的模板来创建,就会自动生成webconfig配置,否则就要添加如下配置到webconfig中:
<system.web>
<compilation debug="true" targetFramework="4.0" />
<httpHandlers>
<add verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*"/>
</httpHandlers>
</system.web> <system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<validation validateIntegratedModeConfiguration="false"/>
<handlers>
<add name="Nancy" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*"/>
</handlers>
</system.webServer>
并且还要确定你添加了Nancy和Nancy.Hosting.Aspnet 两个dll的引用。
方案二:网站中一部分使用Nancy
除了使用Nancy搭建整个网站,我们还可以在已存在的网站中使用Nancy来处理某些特定路径的请求。例如我们要处理nancypath下面的所有请求,我们只需要修改上面的配置NancyHttpRequestHandler的path为path="nancypath/*",并且你也要在项目中添加指定路径的文件夹,并在文件夹内放入如下Web.config:
<?xml version="1.0"?>
<configuration>
<system.web>
<httpHandlers>
<add verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*"/>
</httpHandlers>
</system.web>
</configuration>
除此之外,再修改webconfig中的<location>节点配置。
方案三:在MVC中使用Nancy
是的,你没有看错,Nancy和MVC一起使用,如果要在MVC中使用Nancy,需要修改Global.asax.cs文件,添加如下内容:
routes.IgnoreRoute("nancy/{*pathInfo}");
这个时候,所有访问nancy目录的请求,就都会被Nancy处理了,接下来,我们就可以这样写代码了,例如:
public class Home : NancyModule
{
public Home()
{
Get["/nancy/products"] = x => "The products!";
}
}
这部分详细内容参考:https://github.com/NancyFx/Nancy/wiki/Hosting-Nancy-with-asp.net
2.Hosting Nancy with wcf
如果你想搭建一个轻量级的HTTP服务而又不想使用IIS,Nancy是一个很好的选择,你可以按照下面的操作来实现:
首先,安装Nancy.Hosting.Wcf,Nugget代码如下:
PM> Install-Package Nancy.Hosting.Wcf
然后,编写代码,如下:
var host = new WebServiceHost(new NancyWcfGenericService(),
new Uri("http://localhost:1234/base/"));
host.AddServiceEndpoint(typeof (NancyWcfGenericService), new WebHttpBinding(), "");
host.Open(); // Nancy will now handle requests to http://localhost:1234/base/
然后,Nancy就会侦听本地的1234端口,处理HTTP请求。
这部分详细内容参考:https://github.com/NancyFx/Nancy/wiki/Hosting-Nancy-with-wcf
除此之外,Nancy还有以下Host方式:
Hosting-nancy-with-azure 参考:https://github.com/NancyFx/Nancy/wiki/Hosting-nancy-with-azure
Hosting-nancy-with-owin 参考:https://github.com/NancyFx/Nancy/wiki/Hosting-nancy-with-owin
Hosting-Nancy-with-Umbraco 参考:https://github.com/NancyFx/Nancy/wiki/Hosting-Nancy-with-Umbraco
Hosting-Nancy-with-Nginx-on-Ubuntu 参考:https://github.com/NancyFx/Nancy/wiki/Hosting-Nancy-with-Nginx-on-Ubuntu
Hosting-Nancy-with-FastCgi 参考:https://github.com/NancyFx/Nancy/wiki/Hosting-Nancy-with-FastCgi
Self-Hosting-Nancy 参考:https://github.com/NancyFx/Nancy/wiki/Self-Hosting-Nancy
1、Nancy中的路由机制
在上一篇的博文中,我们都知道Nancy中的所有路由都定义在module中的构造方法中,我们上次定义了一个无参路由,如下:
public class HelloModule : NancyModule
{
public HelloModule()
{
Get["/"] = parameters => "Hello World";
}
}
Nancy中有参路由可以这样定义:
public class ProductsModule : NancyModule
{
public ProductsModule()
{
Get["/products/{id}"] = _ =>
{
//do something
};
}
}
或者定义成异步的,如下:
public class ProductsModule : NancyModule
{
public ProductsModule()
{
Get["/products/{id}", runAsync: true] = async (_, token) =>
{
//do something long and tedious
};
}
}
Nancy中支持的method有:DELETE, GET, HEAD, OPTIONS, POST, PUT and PATCH.
当然,Nancy中还支持路由参数约束,例如我们要求参数必须为int类型,我们可以这样定义:
Get["/intConstraint/{value:int}"] = _ => "Value " + _.value + " is an integer.";
除了int类型,Nancy还支持以下类型的约束:

感觉还不够?Nancy还提供了自定义参数约束,比如我们要求参数是一个email,我们可以先定义如下类:
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;
}
}
然后,定义路由如下:
Get["/profile/{value:email}"] = _ => "Value " + _.value + " is an e-mail address.";
下面是Nancy中路由常用的几种写法:

当然,Nancy的路由机制非常强大、非常灵活,那么当一个地址可以匹配多个路由时,Nancy会选择哪一个呢?其实,Nancy中有一套路由的权重机制来解决路由冲突,这个到后面说路由的时候会详细说的。
2、MVC中的路由机制
我们都知道MVC中的路由配置都在 Global.asax.cs中,当一个ASP.NET MVC应用程序第一次运行时, Application_Start()方法被调用。这个方法,又调用RegisterRoutes()方法,RegisterRoutes()方法创建了路由表。
MVC中的默认路由如下:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute(
"Default", // 路由名称
"{controller}/{action}/{id}", // 带有参数的 URL
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值 (UrlParameter.Optional-可选的意思)
);
}
NVC中无参路由定义如下:
routes.MapRoute
(
"Home",
"{controller}/{action}/{id}"
);
MVC中带命名空间的路由定义如下:
routes.MapRoute(
"AdminControllers", // 路由名称
"{controller}/{id}-{action}", // 带有参数的 URL
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // 参数默认值
new string[] { "Admin.Controllers" }//命名空间
);
MVC中带约束的路由定义如下:
routes.MapRoute(
"RuleControllers",
"{controller}/{action}-{Year}-{Month}-{Day}}",
new { controller = "Home", action = "Index", Year = "", Month = "", Day = "" },
new { Year = @"^\d{4}", Month = @"\d{2}" } //4位数 2位数
);
MVC全局路由:
routes.MapRoute(
"All", // 路由名称
"{*Vauler}", // 带有参数的 URL
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值
);
综上所述,MVC和Nancy的路由机制从功能上来说不相上下,MVC有的Nancy也有。不过,相比之下,Nancy中的路由更加简单、灵活,毕竟MVC中的路由对于新手来说不是那么容易掌握的。
当然,视图这块大家还是比较关注的。下面简单对比MVC和Nancy所支持的视图:
| MVC | Nancy | |
| WebForm | 支持 | 支持 |
| Razor | 支持 | 支持 |
这里我们看到MVC和nancy都支持WebForm和Razor视图。并且,Nancy在Razor视图中也支持Model的绑定和部分视图,在Nancy中的部分视图中,也可以使用Modle绑定。
虽然微软刚刚宣布开源不久,但是在这之前,asp.net就可以通过Mono实现跨平台了。当然MVC和Nancy也可以通过Mono来实现跨平台。
到这里,对在上一篇中所提到的问题,相信大家心中已经有答案了吧~~
作者:雲霏霏
QQ交流群:243633526
博客地址:http://www.cnblogs.com/yunfeifei/
声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权,贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。
如果大家感觉我的博文对大家有帮助,请推荐支持一把,给我写作的动力。
.NET轻量级MVC框架:Nancy入门教程(二)——Nancy和MVC的简单对比的更多相关文章
- Android轻量级ORM框架ActiveAndroid入门教程(转)
注:没有找到出处,如有侵犯,请告知 开始ActiveAndroid神奇之旅: 在AndroidManifest.xml中我们需要添加这两个 AA_DB_NAME (数据库名称,这个name不能改,但是 ...
- Veins(车载通信仿真框架)入门教程(二)——调用第三方库
Veins(车载通信仿真框架)入门教程(二)——调用第三方库 在借助Veins进行自己的研究时我们经常需要实现一些比较复杂的功能,有时就需要借助第三方库的帮助. 博主的研究需要使用神经网络,但是自己编 ...
- 无废话ExtJs 入门教程二十一[继承:Extend]
无废话ExtJs 入门教程二十一[继承:Extend] extjs技术交流,欢迎加群(201926085) 在开发中,我们在使用视图组件时,经常要设置宽度,高度,标题等属性.而这些属性可以通过“继承” ...
- 无废话ExtJs 入门教程二十[数据交互:AJAX]
无废话ExtJs 入门教程二十[数据交互:AJAX] extjs技术交流,欢迎加群(521711109) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C ...
- 无废话ExtJs 入门教程二[Hello World]
无废话ExtJs 入门教程二[Hello World] extjs技术交流,欢迎加群(201926085) 我们在学校里学习任何一门语言都是从"Hello World"开始,这里我 ...
- RabbitMQ入门教程(二):简介和基本概念
原文:RabbitMQ入门教程(二):简介和基本概念 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn ...
- mongodb入门教程二
title: mongodb入门教程二 date: 2016-04-07 10:33:02 tags: --- 上一篇文章说了mongodb最基本的东西,这边博文就在深入一点,说一下mongo的一些高 ...
- SpringBoot入门教程(二)CentOS部署SpringBoot项目从0到1
在之前的博文<详解intellij idea搭建SpringBoot>介绍了idea搭建SpringBoot的详细过程, 并在<CentOS安装Tomcat>中介绍了Tomca ...
- PySide——Python图形化界面入门教程(二)
PySide——Python图形化界面入门教程(二) ——交互Widget和布局容器 ——Interactive Widgets and Layout Containers 翻译自:http://py ...
随机推荐
- CentOS6系统openssl生成证书和自签证书
CentOS6系统openssl生成证书和自签证书的过程,记录一下,本文基于CentOS 6 64bit.$ yum install openssl openssl-devel 1,生成服务器端的私钥 ...
- c#datagirdview ,用DataSource 方式赋值,然后更新出问题问题
先说一下程序 主窗体 ,两个子窗体A,B.嵌入主窗体的Panel里边 主窗体,启动类C里边的查找方法,查到的值,通过事件委托送到窗体A C类里同时修改查询表,把修改的查询表通过事件委托发送给窗体B, ...
- 无域环境下,VCENTER5.5 更改IP后 无法登陆异常修复
转自http://bbs.vmsky.com/forum.php?mod=viewthread&tid=45593&highlight=vcenter%2Bip 由于没有域环境,SSO ...
- ZooKeeper事务日志记录器SyncRequestProcessor
SyncRequestProcessor作为一个ZooKeeper中的一个关键线程(ZooKeeperCriticalThread),是ZooKeeper请求处理链中的事务日志记录处理器,其主要用来将 ...
- Java中实现PHP中的urlencode与rawurlencode
php手册中对urlencode这样说明 在java中 URLEncoder做了这样注释 也就是说java中对星号"*"是不进行编码的 也就是说URLEncoder之后还是&quo ...
- Activity设置全屏的三种方法
1.super.onCreate(savedInstanceState)方法之前调用: setTheme(android.R.style.Theme_Light_NoTitleB ...
- CSAPP读书随笔之一:为什么汇编器会将call指令中的引用的初始值设置为-4
CSAPP,即<深入理解计算机系统:程序员视角>第三版,是一本好书,但读起来确需要具备相当的基本功.而且,有的表述(中译文)还不太直白. 比如,第463页提到,(对于32位系统)为什么汇编 ...
- STAF no JSTAF in java.library.path 的终极解决办法
最近两天在研究利用STAF 实现程序更新包的自动部署测试.运行Demo代码时遇到一个坑.我的安装路径是默认的.C:\STAF\samples\demo在命令行窗口用执行命令:java STAFDemo ...
- php 用户ip的获取
$_SERVER 这个变量我很喜欢,里面有很多服务器和用户的配置.资料.特别是在获取用户ip 的时候 直接$_SERVER['REMOTE_ADDR'] 就可以或许,但这是没有使用 反向代理服务器的情 ...
- rabbitmq集群安装
在配置文件中配置集群没有成功,但是使用命令行成功了,以下是过程请参考. 场景:两台机器,一台是10.1.3.95 hostname为mq1,一台是10.1.3.96 hostname为 ...