花10分钟搞懂开源框架吧 - 【NancyFx.Net】
NancyFx是什么?
Nancy是一个轻量级的独立的框架,下面是官网的一些介绍:
Nancy 是一个轻量级用于构建基于 HTTP 的 Web 服务,基于 .NET 和 Mono 平台,框架的目标是保持尽可能多的方式,并提供一个super-duper-happy-path所有交互。
Nancy 设计用于处理
DELETE
,GET
,HEAD
,OPTIONS
,POST
,PUT
和 PATCH
等请求方法,并提供简单优雅的 DSL 以返回响应。Nancy和Asp.net MVC原理相似,但有自己的一套路由机制,在使用上更加易用,可以用Nancy快速开发一些网站。
Nancy并不依赖任何现有的框架,所以他可以运行在任何平台上面。
其NancyFx官方地址是:http://nancyfx.org/,Nancy这个单词我们中国人的标准叫法 叫做 “南希”。
我们为何要使用它呢?
没有配置
为了让Nancy启动并运行,不需要配置,没有令人讨厌的XML文件可以修改,没有。由于它是主机不可知的,因此您不必修改web.config中的任何内容以使其通过IIS运行。
随处运行
Nancy是主机不可知的,这意味着您可以在IIS,WCF,嵌入在EXE中,作为Windows服务或在自托管应用程序中运行它。到处都是!
在Mono上
Nancy不把自己绑定在Windows上,它在OSX和Mono下的Linux上工作得一样好,这让您的团队可以在多个平台上工作。
如何在.NET上使用NancyFx
创建一个.Net Core App,我们需要在项目中安装NancyFx,通过nuget安装,也可以通过命令行,NancyFx的依赖项可能有OAuth的邀请,大部分OAuth2.11就ok了。
NancyFx.Net 之 HelloWorld
引用完成之后,我们需要修改Startup.cs了,这里我们在Configure中进行注册,其目的是添加到MVC管道中。
- public void Configure(IApplicationBuilder app, IHostingEnvironment env)
- {
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- }
- app.UseOwin(x => x.UseNancy());
- }
接下来我们创建一个模块(类),HelloModule
继承自NancyModule
- public class HelloModule : NancyModule
- {
- public HelloModule() { Get("/", p => "hello world"); }
- }
代码说明&结果:
这里的Get方法有两个参数,第一个参数就是和.NET Core MVC Route 差不多,那么第二个就是action,就是具体的定义,我们启动项目,发现网站正确的显示出了Hello World!
NancyFx.Net 模块
模块你可以在任何地方上声明,只要它运行在你的应用程序域即可,Nancy会自动捕捉作为NancyModule类型后代的所有类型(因为你继承了南希模块)。
我们把代码改一下,通过base去构造模块其中写的是个你想要的路径:
- public class HelloModule : NancyModule
- {
- public HelloModule() : base("hello") { Get("/", p => "hello world"); }
- }
启动项目,我们发现,404找不到了,我们的路由应该是port/hello/ 才对。
NancyFx.Net 路由
路由概念分类
这些我们逐一说一说。
纯文字路由片段(Literal Segment)
含变量的片段(Capture Segment)
含可空变量的片段(Capture Segment - Optional)
正则片段(RegEx Segment)
- 贪婪片段(Greedy Segment)
警告
注意:如果你是在Asp.net Core MVC中使用,必须是2.0预览,如不是Core中,则是1.4.5以下,下面是两个大版本路由语法比较:
- Get["/nancy/products"] = x => "hello world";
- Get("/", p => "hello world");
纯文字路由片段(Literal Segment)
纯文本路由片段我们已经知道了其实,开头的hello,world 即使如此。
含变量的片段(Capture Segment)
- public HelloModule()
- {
- Get("StudentList/{id?}",res=>res.id == null ? "咋不输入呢" : res.id);
- }
这实际上的第二个参数就是一个Func委托,我们可以通过url去获取可变参数的值。
含可空变量的片段(Capture Segment - Optional)
- public HelloModule()
- {
- Get("StudentList/{id?}",res=>res.id == null ? "咋不输入呢" : res.id);
- }
可空类型就是在参数后面加个?就可以了。
正则片段(RegEx Segment)
Nancy的路由是支持正则的
- public HelloModule()
- {
- Get(@"/products/(?<productId>^[1]+[3,5]+\d{9})", p => "Your product id is " + p.productId);
- }
贪婪片段(Greedy Segment)
Nancy中可以在变量尾部追加一个星号,表示当url匹配结束后的字符串
- public class ProductModule : NancyModule
- {
- public ProductModule()
- {
- Get("/products/{productName*}", p => p.productName);
- }
- }
路由片段参数类型约束
只有为int类型的才会被匹配
- public class ProductModule : NancyModule
- {
- public ProductModule()
- {
- Get("/products/{productId:int}", p => "Product id is " + p.productId);
- }
- }
Nancy 前后端交互
如何返回视图,我们尝试着在Views中创建静态文件html(地址为:Views/Student/StudentList.html),并构造moduls返回view视图:
- public HelloModule()
- {
- Get("/", p => View["Student/StudentList.html"]);
- }
F5,启动项目你会发现..
Nancy视图位置约定
Nancy是有一套自己的约定的,那我们也不想和它约定,谁理他呢,我们可以自己自定义约定。
为此,您需要创建一个自定义引导程序,并将您的约定(使用前面描述的函数签名)添加到Conventions.ViewLocationConventions
集合中。首先创建一个CustomRootPathProvider类,继承了IRootPathPrvider.
- public class CustomRootPathProvider : IRootPathProvider
- {
- public string GetRootPath()
- {
- return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Views");
- }
- }
特别提醒:如果是测试环境而并非是生产环境请将路径换为:Directory.GetCurrentDirectory()
通过拼接我们已经将项目的根目录改编成了Views,然后我们再创建一个新类,CustomBootstrapper是为了生效我们自定义的去重写了RootPathProvider。
- public class CustomBootstrapper : DefaultNancyBootstrapper
- {
- protected override IRootPathProvider RootPathProvider
- {
- get
- {
- return new CustomRootPathProvider();
- }
- }
- }
这个时候,原本的Nancy的追踪的功能就已经被我们给kill掉了,如果想要再启动则需要在CustomBootstrapper添加代码如下:
- public override void Configure(INancyEnvironment environment)
- {
- environment.Tracing(enabled: true, displayErrorTraces: true);
- base.Configure(environment);
- }
那么我们现在启动,ok成功了(找到了)!
超级简单视图引擎(NancyFx默认推荐)
超级简单视图引擎,也称为SSVE,是一个正则表达式(实现使用正则表达式执行替换)的视图引擎,旨在支持简单的模板场景.
没有必要安装单独的Nuget来使用引擎,因为它嵌入到主Nancy组件中,并且将自动连接并准备好在您的应用程序中使用。该引擎处理与任何意见
sshtml
,html
或htm
文件扩展名。
标准变量替换:
如果未指定参数,则替换参数的字符串表示形式或模型本身。如果无法执行替换,例如,如果指定了无效的模型属性,则将替换为[Err!]
句法
- @Model[.Parameters]
例
- Hello @Model.Name, your age is @Model.User.Age
迭代:
使您可以迭代集合的模型。迭代器不能嵌套,语法如下:
@Each[.Parameters]
[@Current[.Parameters]]
@EndEach
我们将StudentList作为参数传入到我们的视图中,代码定义如下:
Student类的简单定义:
- public class Student
- {
- public int StudentID { get; set; }
- public string StudentName { get; set; }
- }
Module.cs的定义:
- public class HelloModule : NancyModule
- {
- List<Student> list = new List<Student>()
- {
- new Student(){ StudentID =1 , StudentName = "张子浩"},
- new Student(){ StudentID =2 , StudentName = "张得帅"},
- new Student(){ StudentID =3 , StudentName = "张大彪"}
- };
- public HelloModule()
- {
- Get("/hello", p => {
- return View["hello.html", new
- {
- list
- }];
- });
- }
- }
hello.html:
- <table>
- <tr>
- ISBN
- </tr>
- <tr>
- Book Name
- </tr>
- <tbody>
- @Each.list
- <tr>
- <td>
- @Current.StudentID
- </td>
- <td>
- @Current.StudentName
- </td>
- </tr>
- @EndEach
- </tbody>
- </table>
条件:
参数必须是布尔值(请参阅下面的隐式条件)。不支持嵌套@If和@IfNot语句,语法如下:
@If[Not].Parameters
[contents]
@EndIf
栗子:
- @IfNot.HasUsers
- No users found!
- @EndIf
我们在Student实体中添加了一个布尔值为了给其中的示例做出演示:
- public class HelloModule : NancyModule
- {
- List<Student> list = new List<Student>()
- {
- new Student(){ StudentID =1 , StudentName = "张子浩",isDisplay = false},
- new Student(){ StudentID =2 , StudentName = "张得帅",isDisplay=false},
- new Student(){ StudentID =3 , StudentName = "张大彪",isDisplay=true}
- };
- public HelloModule()
- {
- Get("/hello", p => {
- return View["hello.html", new
- {
- list
- }];
- });
- }
- }
- public class Student
- {
- public int StudentID { get; set; }
- public string StudentName { get; set; }
- public bool isDisplay { get; set; }
- }
hello.html:
- <table>
- <tr>
- ISBN
- </tr>
- <tr>
- Book Name
- </tr>
- <tbody>
- @Each.list
- @If.isDisplay
- <tr>
- <td>
- @Current.StudentID
- </td>
- <td>
- @Current.StudentName
- </td>
- </tr>
- @EndIf
- @EndEach
- </tbody>
- </table>
Partial View
呈现局部视图。可以指定当前模型的属性以用作局部视图的模型,或者可以省略它以使用当前视图的模型。视图的文件扩展名是可选的。
语法:
- @Partial['<view name>'[, Model.Property]]
例:
- //只返回视图
- @Partial['subview.sshtml'];
- //带模型的
- @Partial['subview.sshtml', Model.User];
我们创建一个html,名为Partial.html,定义如下:
<body>
部分View: @Model
</body>
hello.html:
- <table>
- <tr>
- ISBN
- </tr>
- <tr>
- Book Name
- </tr>
- <tbody>
- @Each.list
- <tr>
- <td>
- @Current.StudentID
- </td>
- <td>
- @Partial['Partial.html',Model.StudentName]
- </td>
- </tr>
- @EndEach
- </tbody>
- </table>
如果不需要去构造部分视图的内部实体,那么你就不用传第二个参数。
南希生命周期
当接收到客户端的请求之后,我们回到南希的管道中,分析了路由和一些模块规则,通过使用irouteinvoker调用路由,返回对应的静态文件,通过钩子继续配置引导程序,看看是否报错,没有的话直接通过Handler返回response。
评价NancyFx
在2016年Nancy就停止了更新,它是一个类似于mvc的框架,个人认为它的路由机制很不错,但是视图用起来不是很舒服,还是没人支持啊!
花10分钟搞懂开源框架吧 - 【NancyFx.Net】的更多相关文章
- 10分钟搞懂Tensorflow 逻辑回归实现手写识别
1. Tensorflow 逻辑回归实现手写识别 1.1. 逻辑回归原理 1.1.1. 逻辑回归 1.1.2. 损失函数 1.2. 实例:手写识别系统 1.1. 逻辑回归原理 1.1.1. 逻辑回归 ...
- 10分钟搞懂toString和valueOf函数(详细版)
首先要说明的是这两种方法是toPrimitive抽象操作里会经常用到的. 默认情况下,执行这个抽象操作时会先执行valueOf方法,如果返回的不是原始值,会继续执行toString方法,如果返回的还不 ...
- 干货 | 10分钟搞懂branch and bound(分支定界)算法的代码实现附带java代码
Outline 前言 Example-1 Example-2 运行说明 00 前言 前面一篇文章我们讲了branch and bound算法的相关概念.可能大家对精确算法实现的印象大概只有一个,调用求 ...
- c#代码 天气接口 一分钟搞懂你的博客为什么没人看 看完python这段爬虫代码,java流泪了c#沉默了 图片二进制转换与存入数据库相关 C#7.0--引用返回值和引用局部变量 JS直接调用C#后台方法(ajax调用) Linq To Json SqlServer 递归查询
天气预报的程序.程序并不难. 看到这个需求第一个想法就是只要找到合适天气预报接口一切都是小意思,说干就干,立马跟学生沟通价格. 不过谈报价的过程中,差点没让我一口老血喷键盘上,话说我们程序猿的人 ...
- 【转】让你10分钟搞定Mac--最简单快速的虚拟安装
文章出处:让你10分钟搞定Mac--最简单快速的虚拟安装http://bbs.itheima.com/thread-106643-1-1.html (出处: 黑马程序员训练营论坛) 首先说明一下. 第 ...
- [转帖]10分钟看懂Docker和K8S
10分钟看懂Docker和K8S https://zhuanlan.zhihu.com/p/53260098 2010年,几个搞IT的年轻人,在美国旧金山成立了一家名叫“dotCloud”的公司. 这 ...
- 五分钟搞懂POM设计模式
转载请注明出处️ 作者:IT小学生蔡坨坨 原文链接:五分钟搞懂POM设计模式 大家好,我是IT小学生蔡坨坨. 今天,我们来聊聊Web UI自动化测试中的POM设计模式. 为什么要用POM设计模式 前期 ...
- 【MySQL】花10分钟阅读下MySQL数据库优化总结
1.花10分钟阅读下MySQL数据库优化总结http://www.kuqin.com2.扩展阅读:数据库三范式http://www.cnblogs.com3.my.ini--->C:\Progr ...
- OpenCV3.4.1快速集成到Android studio中,10分钟搞定
OpenCV3.4.1快速集成到Android studio中,10分钟搞定 转载 https://blog.csdn.net/yu540135101/article/details/8259 ...
随机推荐
- 【spring】-- springboot配置全局异常处理器
一.为什么要使用全局异常处理器? 什么是全局异常处理器? 就是把错误异常统一处理的方法. 应用场景: 1.当你使用jsr303参数校验器,如果参数校验不通过会抛异常,而且无法使用try-catch语句 ...
- git 的常用命令(未完待补充)
一.初始化 git git init 这样会默认创建 master 分支 二.查看当前状态 git status 查看 git 的默认状态 三.创建一个文件,并把它添加到 git 仓库,使用 git ...
- nodejs中的Buffer
一,开篇分析 所谓缓冲区Buffer,就是 "临时存贮区" 的意思,是暂时存放输入输出数据的一段内存. JS语言自身只有字符串数据类型,没有二进制数据类型,因此NodeJS提供了一 ...
- AI零基础入门之人工智能开启新时代—上篇
人工智能的发展史及应用 开篇:人工智能无处不在 人工智能的发展历程 · 1945艾伦图灵在论文<计算机器不智能>中提出了著名的图灵测试,给人工智能的収展产生了深远的影响. · 1951年, ...
- SpringMVC之拦截器的的配置和使用
拦截器与过滤器的区别:拦截器只能拦截controller的请求,过滤器可以过滤所有请求 (1)实现HandlerInterceptor接口 在执行控制器中的方法之前执行preHandle()中的方法 ...
- iptables安装
1.安装iptable iptable-service #先检查是否安装了iptables service iptables status #安装iptables yum install -y ipt ...
- synchronized 与 volatile 原理 —— 内存屏障的重要实践
单例模式的双重校验锁的实现: 第一种: private static Singleton _instance; public static synchronized Singleton getInst ...
- post数据时报错:远程服务器返回错误: (400) 错误的请求。
网上查了多种方法,有不少说法,报400说是传的数据格式不对,最后的结论确实是数据格式不对. Content_Type为:application/json,配的数据格式有些麻烦,特别数多层,单层还好.例 ...
- excel写入操作
字典列表类型数据写入excel. #导入xlwt库 import xlwt import os # 步骤1:获取excel文件的绝对路径 dirPath = os.path.join(os.getcw ...
- window server 2008 安装Oracle10g
oracle安装都大同小异. 开始安装步骤 输入完之后点击下一步 这时候稍等一会儿. 这时候也要稍等一会儿. 直接安装. 设置口令管理,设置SCOTT的密码为tiger就好了. 这时候稍等一会儿. o ...