前文中我们介绍了Nancy中的路由,这一篇我们来介绍一下Nancy中的视图引擎。

Nancy中如何返回一个视图(View)

在ASP.NET Mvc中,我们使用ViewResult类来返回一个视图。Nancy中也提供了类似的功能, 在NancyModule类中,Nancy提供了一个ViewRenderer类型的View的属性来返回视图。

ViewRenderer类代码如下,该类中提供了三个属性访问器

    public class ViewRenderer : IHideObjectMembers
{
public ViewRenderer(INancyModule module); public Negotiator this[[Dynamic] dynamic model] { get; } public Negotiator this[string viewName] { get; } public Negotiator this[string viewName, [Dynamic] dynamic model] { get; }
}

public Negotiator this[string viewName] - 仅指定呈现的数据模型, Nancy会根据url自动匹配一个View文件

public Negotiator this[string viewName] - 仅指定返回的View文件名

public Negotiator this[string viewName, [Dynamic] dynamic model] - 不仅指定的View的文件名,还指定了用于呈现的数据模型

下面我们修改之前的HelloModule.cs, 添加一个/hello的路由模板, 并使用View属性来返回一个视图

    public class HelloModule : NancyModule
{
public HelloModule()
{
Get("/hello", p => View["hello.html"]);
}
}

然后我们创建一个wwwroot目录,并在其中添加一个hello.html, 里面的代码如下

<h1>Hello World</h1>

现在我们启动项目, 并输入/hello, 浏览器返回的结果如下。

不要慌张,这说明我们的请求被Nancy处理了,只是因为在服务器上没有正确找到hello.html这个文件,所以报错了,继续看完下一节的内容,你的页面就能正确显示。

Nancy中的视图位置约定

Nancy中官网文档中介绍了好几种视图的位置约定,它定义了Nancy中搜索视图文件的顺序和方式。

我们用以下代码为例

    public class HelloModule : NancyModule
{
public HelloModule()
{
Get("/hello", p => View["hello.html"]);
}
}

当/hello请求进入Nancy管道后,我们决定使用hello.html作为响应页面,当Nancy尝试寻找这个页面时,

  • Nancy首先会去寻找网站根目录下"/views/[模块名]/[指定页面文件名]", 如果找的到该文件,Nancy即读取该页面内容,并绑定数据模型返回给客户端,这就是View and Module Name约定。在当前例子中即/views/Hello/hello.html
  • 如果找不到文件,Nancy会继续寻找网站根目录下"/[模块名]/[指定页面文件名]", 这就是Module Name约定。当前例子中即/Hello/hello.html
  • 如果还是找不到文件,Nancy会继续寻找网站根目录下"/views/[指定页面文件名]", 这就是View Folder Name约定。当前例子中即/views/hello.html
  • 如果还是找不到文件,Nancy最终会去寻找网站根目录下"/[指定页面文件名]",这就是Root约定。当前例子中即/hello.html
  • 如果都找不到, Nancy会返回一个错误页

切换网站根目录

在.NET Core中我们通常会将静态文件方式在wwwroot目录中, 而非网站根目录 这样会导致Nancy不能正确访问到正确的静态文件。这里我们就需要去修改Nancy默认的网站根目录设置。

Nancy我们可以通过实现IRootPathProvider接口的GetRootPath方法, 并覆盖DefaultNancyBootstrapper类中的RootPathProvider属性来实现自定义网站根目录。

首先我们创建一个新类CustomRootPathProvider

    public class CustomRootPathProvider : IRootPathProvider
{
public string GetRootPath()
{
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wwwroot");
}
}

代码中通过拼接目录, 我们将当前网站的根目录指向了wwwroot。

然后我们创建一个新类CustomBootstrapper, 让它继承NancyDefaultBootstrapper类并使用CustomerRootPathProvider作为Nancy的RootPathProvider。

    public class CustomBootstrapper : DefaultNancyBootstrapper
{
protected override IRootPathProvider RootPathProvider
{
get
{
return new CustomRootPathProvider();
}
}
}

特别注意:当创建自定义Bootstrapper之后,之前的Nancy的Trace功能会被屏蔽掉,如果想重新启用Trace功能,需要在CustomBootstrapper中加入如下代码。

    public override void Configure(INancyEnvironment environment)
{
environment.Tracing(enabled: true, displayErrorTraces: true);
base.Configure(environment);
}

现在我们重启项目, 输入/hello, 页面正确显示了。

Nancy中支持的视图引擎

Nancy中支持的视图引擎如下

  • Super Simple View Engine(SSVE)
  • Razor
  • Spark
  • NDjango
  • dotLiquid

这里我们重点说明一下SSVE。

超级简单的视图引擎(Super Simple View Engine)

Super Simple View Engine, 简称SSVE, 是Nancy默认提供的视图引擎, 我们前面的例子使用的就是SSVE视图引擎。

下面我们介绍一个SSVE视图引擎的一些基本语法

输入变量的值

语法:

@Model[.Parameters]

例:

BookModule.cs

    public class BookModule : NancyModule
{
public BookModule()
{
Get("/books/{bookId}", p => View["book.html", new { BookId = p.bookId }]);
}
}

book.html

The Book Id is @Model.BookId

迭代

语法:

@Each[.Parameters]
[@Current[.Parameters]]
@EndEach

例:

BookModule.cs

    public class BookModule : NancyModule
{
public BookModule()
{
Get("/books", p =>
{
return View["books.html", new
{
Books = new List<Book> {
new Book("S001", "Math 101"),
new Book("T001", "C# Programming")
}
}];
});
}
} public class Book
{
public Book(string isbn, string bookName)
{
ISBN = isbn;
BookName = bookName;
} public string ISBN { get; set; } public string BookName { get; set; }
}

books.html

<table>
<tr>
ISBN
</tr>
<tr>
Book Name
</tr>
<tbody>
@Each.Books
<tr>
<td>
@Current.ISBN
</td>
<td>
@Current.BookName
</td>
</tr>
@EndEach
</tbody>
</table>

条件

语法

@If[Not].Parameters
[contents]
@EndIf

注意:这里只支持bool类型的变量,不支持表达式

例:

BookModule.cs

    public class BookModule : NancyModule
{
public BookModule()
{
Get("/books", p =>
{
return View["booksWithIf.html", new
{
Books = new List<Book> {
new Book("S001", "Math 101", true),
new Book("T001", "C# Programming", false)
}
}];
});
}
} public class Book
{
public Book(string isbn, string bookName, bool isNew)
{
ISBN = isbn;
BookName = bookName;
IsNew = isNew;
} public string ISBN { get; set; } public string BookName { get; set; } public bool IsNew { get; set; }
}

booksWithIf.html

<table>
<tr>
ISBN
</tr>
<tr>
Book Name
</tr>
<tbody>
@Each.Books @If.IsNew
<tr>
<td>
@Current.ISBN
</td>
<td>
@Current.BookName
</td>
</tr>
@EndIf
@EndEach
</tbody>
</table>

输出Partial View

语法

@Partial['<view name>'[, Model.Property]]

例:

BookModule.cs

    public class BookModule : NancyModule
{
public BookModule()
{
Get("/books/{bookId}", p => View["bookWithPartial.html", new { BookId = p.bookId }]);
}
}

partial.html

<h1>Hello Nancy</h1>

bookWithParital.html

The Book Id is @Model.BookId

@Partial['partial.html']

模板页

语法:

@Master['<name>']

@Section['<name>']
@EndSection

例:

BookModule.cs

public class BookModule : NancyModule
{
public BookModule()
{
Get("/books/{bookId}", p => View["bookWithMaster.html", new { BookId = p.bookId }]);
}
}

bookWithMaster.html

@Master['master.html']

@Section['content']
The Book Id is @Model.BookId
@EndSection

master.html

<h1>This is just an example</h1>

<div style="border:1px solid #000;width:200px;">
@Section['Content'];
</div>

Razor

SSVE视图引擎虽然很简单,但是提供的方法不多,应对许多复杂场景,都需要去自定义语法模板。

除了SSVE, Nancy中还可以使用和ASP.NET Mvc中一样的Razor视图引擎, 其中的语法和使用方式与ASP.NET Mvc中的Razor引擎基本一样。但是需要注意的是Nancy.Viewengines.Razor还没有完成针对.NET Stardard重写,所以如果想在Nancy中使用Razor引擎的同学只能在非.NET Core项目中使用它, 相关的教程请参见官网

总结

Nancy的视图引擎自2016.12月之后就没有再发布了, 个人感觉Nancy现在发展的重点已经不再视图引擎上了, Nancy更多的作为WebApi来使用,最近有发现一本书,介绍了Nancy的微服务实践,有兴趣的同学可以一起读一下。

Microservices in .NET Core with Examples in Nancy

本篇博客源代码

下一篇我们一起来学习Nancy中的数据模型绑定。

Nancy in .Net Core学习笔记 - 视图引擎的更多相关文章

  1. Nancy in .NET Core学习笔记 - 路由

    前文中,我介绍了Nancy的来源和优点,并创建了一个简单的Nancy应用,在网页中输出了一个"Hello World",本篇我来总结一下Nancy中的路由 Nancy中的路由的定义 ...

  2. Nancy in .Net Core学习笔记 - 初识Nancy

    前言 去年11月份参加了青岛MVP线下活动,会上老MVP衣明志介绍了Nancy, 一直没有系统的学习一下,最近正好有空,就结合.NET Core学习总结了一下. 注: 本文中大部分内容都是对官网文档的 ...

  3. .NET CORE学习笔记系列(2)——依赖注入【1】控制反转IOC

    原文:https://www.cnblogs.com/artech/p/net-core-di-01.html 一.流程控制的反转 IoC的全名Inverse of Control,翻译成中文就是“控 ...

  4. .NET CORE学习笔记系列(2)——依赖注入【3】依赖注入模式

    原文:https://www.cnblogs.com/artech/p/net-core-di-03.html IoC主要体现了这样一种设计思想:通过将一组通用流程的控制权从应用转移到框架中以实现对流 ...

  5. .NET CORE学习笔记系列(2)——依赖注入【2】基于IoC的设计模式

    原文:https://www.cnblogs.com/artech/p/net-core-di-02.html 正如我们在<控制反转>提到过的,很多人将IoC理解为一种“面向对象的设计模式 ...

  6. .NET CORE学习笔记系列(2)——依赖注入[7]: .NET Core DI框架[服务注册]

    原文https://www.cnblogs.com/artech/p/net-core-di-07.html 包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的IS ...

  7. .NET CORE学习笔记系列(2)——依赖注入[6]: .NET Core DI框架[编程体验]

    原文https://www.cnblogs.com/artech/p/net-core-di-06.html 毫不夸张地说,整个ASP.NET Core框架是建立在一个依赖注入框架之上的,它在应用启动 ...

  8. .NET CORE学习笔记系列(2)——依赖注入[5]: 创建一个简易版的DI框架[下篇]

    为了让读者朋友们能够对.NET Core DI框架的实现原理具有一个深刻而认识,我们采用与之类似的设计构架了一个名为Cat的DI框架.在上篇中我们介绍了Cat的基本编程模式,接下来我们就来聊聊Cat的 ...

  9. .NET CORE学习笔记系列(2)——依赖注入[4]: 创建一个简易版的DI框架[上篇]

    原文https://www.cnblogs.com/artech/p/net-core-di-04.html 本系列文章旨在剖析.NET Core的依赖注入框架的实现原理,到目前为止我们通过三篇文章从 ...

随机推荐

  1. Kafka消费者组再均衡问题

    在Kafka中,当有新消费者加入或者订阅的topic数发生变化时,会触发Rebalance(再均衡:在同一个消费者组当中,分区的所有权从一个消费者转移到另外一个消费者)机制,Rebalance顾名思义 ...

  2. phpstudy配置本地https

    百度经验(me'i经过测试) 首先申请免费的ssl证书,很多地方都可以申请.我是在腾讯云!如图 下载证书备份好.以免丢失.解压下载的证书,里面有4个文件夹相对应不同的安装环境,我们用的是Apache, ...

  3. Jmeter中主要管理器功用

    不管是在使用jmeter进行性能测试还是接口自动化测试时经常用到各种管理器进行对参数的处理,但是有时候分不清几种管理器的具体用法,所以做个笔记,列一下吧(所列内容基于版本为3.2) 主要内容包含以下: ...

  4. 第三方npm包安装失败

    最近升级一些第三方库,老是出现无法正常安装npm的现象. 一.问题现象 1.webpack4安装失败 // 报错信息 webpack Maximum call stack size exceeded ...

  5. GitLab在centos7上安装和使用

    git的优点 git是分布式的,svn不是 git分布式本地就可以用,可以随便保存各种历史痕迹,不用担心污染服务器,连不上服务器也能提交代码.查看log. GIT分支和SVN的分支不同 分支在SVN中 ...

  6. 资源验证(Modified)

    Last-Modified : 上次修改时间 配合 If-Modified-Since 或者 If-Unmodified-Since  (请求头携带) 对比上次修改时间对资源进行验证 Etag验证 数 ...

  7. IIS 程序池与Site 导出、导入

    如何在IIS7或IIS7.5中导入导出站点及应用程序池. 为实现负载平衡,我们可能会使用多个WEB服务器,也就会需要给多个IIS配置同样的站点和应用程序池.那么我们需要一个一个的重新建吗?当然不用,我 ...

  8. Mac_Sublime Text3(mac)一些插件和快捷键

    下载地址http://www.sublimetext.com/3 一.安装Package Control 按Ctrl + ` 调出console,粘贴下列安装代码到底部命令行并回车: import u ...

  9. ipset和iptables配合来自动封闭和解封有问题的IP

    iptables封掉少量ip处理是没什么问题的,但是当有大量ip攻击的时候性能就跟不上了,iptables是O(N)的性能.而ipset就像一个集合,把需要封闭的ip地址放入这个集合中,ipset 是 ...

  10. postgrel执行VACUUM报VACUUM cannot run inside a transaction block

    在python脚本里执行: sql_gp1 = "VACUUM dwd_access_record_inout_temp" sql_gp2 = "delete from ...