zoukankan      html  css  js  c++  java
  • 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;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中的数据模型绑定。

  • 相关阅读:
    Asp.net 基础4(自定义控件的使用之客户端脚本生成)
    Asp.net 基础3(自定义控件的使用)
    wpf 可以取消的单选checkbox
    wpf MaskedTextBox
    自定义 日期格式的datePicker
    wpf datagrid no record found style
    Sql语句绝妙用法
    .net反射简介
    c# 正则表达式小结
    如何获取地址栏地址
  • 原文地址:https://www.cnblogs.com/lwqlun/p/9629185.html
Copyright © 2011-2022 走看看