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中的数据模型绑定。

  • 相关阅读:
    WF4.0 Beta1 自定义跟踪
    WF4.0 Beta1 流程设计器与Activity Designer
    新版本工作流平台的 (二) 权限算法(组织结构部分)
    WF4.0 Beta1 WorkflowInvoker
    WF4.0 基础篇 (十) Collection 集合操作
    WF4.0 基础篇 (十五) TransactionScope 事物容器
    WF4.0 基础篇 (六) 数据的传递 Arguments 参数
    WF4B1 的Procedural Activity 之InvokeMethod , InvokeMethod<T> 使用
    WF4.0 Beta1 异常处理
    WF4.0 Beta1 变量 Variables
  • 原文地址:https://www.cnblogs.com/lwqlun/p/9629185.html
Copyright © 2011-2022 走看看