花10分鍾搞懂開源框架吧 - 【NancyFx.Net】


NancyFx是什么?

  Nancy是一個輕量級的獨立的框架,下面是官網的一些介紹:

  Nancy 是一個輕量級用於構建基於 HTTP 的 Web 服務,基於 .NET 和 Mono 平台,框架的目標是保持盡可能多的方式,並提供一個super-duper-happy-path所有交互。

  Nancy 設計用於處理 DELETEGETHEADOPTIONSPOSTPUT 和 PATCH 等請求方法,並提供簡單優雅的 DSL 以返回響應。

  Nancy和Asp.net MVC原理相似,但有自己的一套路由機制,在使用上更加易用,可以用Nancy快速開發一些網站。

  Nancy並不依賴任何現有的框架,所以他可以運行在任何平台上面。

其NancyFx官方地址是:http://nancyfx.org/,Nancy這個單詞我們中國人的標准叫法 叫做 “南希”。

我們為何要使用它呢?

沒有配置

為了讓Nancy啟動並運行,不需要配置,沒有令人討厭的XML文件可以修改,沒有。由於它是主機不可知的,因此您不必修改web.config中的任何內容以使其通過IIS運行。

 隨處運行

Nancy是主機不可知的,這意味着您可以在IIS,WCF,嵌入在EXE中,作為Windows服務或在自托管應用程序中運行它。到處都是!

在Mono上

Nancy不把自己綁定在Windows上,它在OSX和Mono下的Linux上工作得一樣好,這讓您的團隊可以在多個平台上工作。

 如何在.NET上使用NancyFx

 創建一個.Net Core App,我們需要在項目中安裝NancyFx,通過nuget安裝,也可以通過命令行,NancyFx的依賴項可能有OAuth的邀請,大部分OAuth2.11就ok了。

NancyFx.Net 之 HelloWorld

引用完成之后,我們需要修改Startup.cs了,這里我們在Configure中進行注冊,其目的是添加到MVC管道中。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
    
        app.UseOwin(x => x.UseNancy());
    }

 接下來我們創建一個模塊(類),HelloModule繼承自NancyModule

 public class HelloModule : NancyModule
    {
        public HelloModule() { Get("/", p => "hello world"); }
    }

 代碼說明&結果:

這里的Get方法有兩個參數,第一個參數就是和.NET Core MVC Route 差不多,那么第二個就是action,就是具體的定義,我們啟動項目,發現網站正確的顯示出了Hello World!

 

 NancyFx.Net 模塊

模塊你可以在任何地方上聲明,只要它運行在你的應用程序域即可,Nancy會自動捕捉作為NancyModule類型后代的所有類型(因為你繼承了南希模塊)。

 我們把代碼改一下,通過base去構造模塊其中寫的是個你想要的路徑:

public class HelloModule : NancyModule
    {
        public HelloModule() : base("hello") { Get("/", p => "hello world"); }
    }

啟動項目,我們發現,404找不到了,我們的路由應該是port/hello/  才對。

NancyFx.Net 路由

路由概念分類

 這些我們逐一說一說。

  • 純文字路由片段(Literal Segment)

  • 含變量的片段(Capture Segment)

  • 含可空變量的片段(Capture Segment - Optional)

  • 正則片段(RegEx Segment)

  • 貪婪片段(Greedy Segment)

警告

注意:如果你是在Asp.net Core MVC中使用,必須是2.0預覽,如不是Core中,則是1.4.5以下,下面是兩個大版本路由語法比較:

Get["/nancy/products"] = x => "hello world";
Get("/", p => "hello world");

純文字路由片段(Literal Segment)

 純文本路由片段我們已經知道了其實,開頭的hello,world 即使如此。

含變量的片段(Capture Segment)

 public HelloModule()
        {
            Get("StudentList/{id?}",res=>res.id == null ? "咋不輸入呢" : res.id);
        }

 這實際上的第二個參數就是一個Func委托,我們可以通過url去獲取可變參數的值。

含可空變量的片段(Capture Segment - Optional)

 public HelloModule()
        {
            Get("StudentList/{id?}",res=>res.id == null ? "咋不輸入呢" : res.id);
        }

可空類型就是在參數后面加個?就可以了。

正則片段(RegEx Segment)

 Nancy的路由是支持正則的

 public HelloModule()
        {
            Get(@"/products/(?<productId>^[1]+[3,5]+\d{9})", p => "Your product id is " + p.productId);
        }

貪婪片段(Greedy Segment)

 Nancy中可以在變量尾部追加一個星號,表示當url匹配結束后的字符串

public class ProductModule : NancyModule
    {
        public ProductModule()
        {
            Get("/products/{productName*}", p => p.productName);
        }
    }

路由片段參數類型約束

只有為int類型的才會被匹配

    public class ProductModule : NancyModule
    {
        public ProductModule()
        {
            Get("/products/{productId:int}", p => "Product id is " + p.productId);
        }
    }

Nancy 前后端交互

如何返回視圖,我們嘗試着在Views中創建靜態文件html(地址為:Views/Student/StudentList.html),並構造moduls返回view視圖:

public HelloModule()
        {
            Get("/", p => View["Student/StudentList.html"]);
        }

 

F5,啟動項目你會發現..

Nancy視圖位置約定

Nancy是有一套自己的約定的,那我們也不想和它約定,誰理他呢,我們可以自己自定義約定。

為此,您需要創建一個自定義引導程序,並將您的約定(使用前面描述的函數簽名)添加到Conventions.ViewLocationConventions集合中。首先創建一個CustomRootPathProvider類,繼承了IRootPathPrvider.

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

特別提醒:如果是測試環境而並非是生產環境請將路徑換為:Directory.GetCurrentDirectory()

通過拼接我們已經將項目的根目錄改編成了Views,然后我們再創建一個新類,CustomBootstrapper是為了生效我們自定義的去重寫了RootPathProvider。

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

這個時候,原本的Nancy的追蹤的功能就已經被我們給kill掉了,如果想要再啟動則需要在CustomBootstrapper添加代碼如下:

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

 那么我們現在啟動,ok成功了(找到了)!

超級簡單視圖引擎(NancyFx默認推薦)

超級簡單視圖引擎,也稱為SSVE,是一個正則表達式(實現使用正則表達式執行替換)的視圖引擎,旨在支持簡單的模板場景.

沒有必要安裝單獨的Nuget來使用引擎,因為它嵌入到主Nancy組件中,並且將自動連接並准備好在您的應用程序中使用。該引擎處理與任何意見sshtmlhtmlhtm文件擴展名。

標准變量替換:

如果未指定參數,則替換參數的字符串表示形式或模型本身。如果無法執行替換,例如,如果指定了無效的模型屬性,則將替換為[Err!]

句法

@Model[.Parameters]

Hello @Model.Name, your age is @Model.User.Age

迭代:

使您可以迭代集合的模型。迭代器不能嵌套,語法如下:

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

我們將StudentList作為參數傳入到我們的視圖中,代碼定義如下:

Student類的簡單定義:

public class Student
    {
        public int StudentID { get; set; }
        public string  StudentName { get; set; }
    }

Module.cs的定義:

public class HelloModule : NancyModule
    {
        List<Student> list = new List<Student>()
        {
            new Student(){  StudentID =1 , StudentName = "張子浩"},
            new Student(){  StudentID =2 , StudentName = "張得帥"},
            new Student(){  StudentID =3 , StudentName = "張大彪"}
        };
        public HelloModule()
        {
            Get("/hello", p => {
                return View["hello.html", new
                {
                    list
                }];
            });
        }
            
    }

 hello.html:

<table>
        <tr>
            ISBN
        </tr>
        <tr>
            Book Name
        </tr>
        <tbody>
            @Each.list
            <tr>
                <td>
                    @Current.StudentID
                </td>
                <td>
                    @Current.StudentName
                </td>
            </tr>
            @EndEach
        </tbody>
    </table>

  

  

 條件:

參數必須是布爾值(請參閱下面的隱式條件)。不支持嵌套@If和@IfNot語句,語法如下:

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

栗子:

@IfNot.HasUsers
   No users found!
@EndIf

我們在Student實體中添加了一個布爾值為了給其中的示例做出演示:

public class HelloModule : NancyModule
    {
        List<Student> list = new List<Student>()
        {
            new Student(){  StudentID =1 , StudentName = "張子浩",isDisplay = false},
            new Student(){  StudentID =2 , StudentName = "張得帥",isDisplay=false},
            new Student(){  StudentID =3 , StudentName = "張大彪",isDisplay=true}
        };
        public HelloModule()
        {
            Get("/hello", p => {
                return View["hello.html", new
                {
                    list
                }];
            });
        }
            
    }
    public class Student
    {
        public int StudentID { get; set; }
        public string  StudentName { get; set; }
        public bool isDisplay { get; set; }
    }

 

  hello.html:

<table>
        <tr>
            ISBN
        </tr>
        <tr>
            Book Name
        </tr>
        <tbody>
            @Each.list
            @If.isDisplay
            <tr>
                <td>
                    @Current.StudentID
                </td>
                <td>
                    @Current.StudentName
                </td>
            </tr>
            @EndIf
            @EndEach
        </tbody>
    </table>

 Partial View

呈現局部視圖。可以指定當前模型的屬性以用作局部視圖的模型,或者可以省略它以使用當前視圖的模型。視圖的文件擴展名是可選的。

語法:

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

例:

//只返回視圖
@Partial['subview.sshtml'];
//帶模型的
@Partial['subview.sshtml', Model.User];

 我們創建一個html,名為Partial.html,定義如下:

<body>
  部分View: @Model
</body>

 hello.html:

<table>
        <tr>
            ISBN
        </tr>
        <tr>
            Book Name
        </tr>
        <tbody>
            @Each.list
            <tr>
                <td>
                    @Current.StudentID
                </td>
                <td>
                    @Partial['Partial.html',Model.StudentName]
                </td>
            </tr>
            @EndEach
        </tbody>
    </table>

如果不需要去構造部分視圖的內部實體,那么你就不用傳第二個參數。

南希生命周期

nancypipeline

評價NancyFx

在2016年Nancy就停止了更新,它是一個類似於mvc的框架,個人認為它的路由機制很不錯,但是視圖用起來不是很舒服,還是沒人支持啊!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM