Nancy in .Net Core學習筆記

來源:互聯網
上載者:User

前文中我們介紹了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中的資料模型綁定。


Lamond Lu
出處:www.cnblogs.com/lwqlun/p/9629185.html
本站使用「署名 4.0 國際」創作共用協議,請在文章明顯位置註明作者及出處。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.