Nancy in .Net Core學習筆記
前文中我們介紹了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在微服務實踐,有興趣的同學可以一起讀一下。
下一篇我們一起來學習Nancy中的資料模型繫結。
作者:Lamond Lu出處:https://www.cnblogs.com/lwqlun/p/9629185.html 本站使用「署名 4.0 國際」創作共享協議,轉載請在文章明顯位置註明作者及出處。