Nancy之靜態文件處理

来源:http://www.cnblogs.com/catcher1994/archive/2016/01/27/5162917.html
-Advertisement-
Play Games

Nancy中關於靜態文件(Js、css等)的處理


今天我們來談談Nancy中的靜態文件(JavaScript,CSS等)該如何處理。

在前面的Demo中,我們也已經用到了這一塊的內容,

但並沒有深入理解,只是停留在使用的層面上。

在進入今天的正題之前,我們先來簡單看看我們熟悉的ASP.NET MVC中是如何管理我們項目中的這些靜態文件呢?

其實當我們新建一個MVC的項目時,已經生成了一個“模板”讓我們參考,

這個“模板”就是App_Start下麵的 BundleConfig.cs

 1     public class BundleConfig
 2     {
 3         // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862
 4         public static void RegisterBundles(BundleCollection bundles)
 5         {
 6             bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
 7                         "~/Scripts/jquery-{version}.js"));
 8             bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
 9                         "~/Scripts/jquery.validate*"));
10             // Use the development version of Modernizr to develop with and learn from. Then, when you're
11             // ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
12             bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
13                         "~/Scripts/modernizr-*"));
14             bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
15                       "~/Scripts/bootstrap.js",
16                       "~/Scripts/respond.js"));
17             bundles.Add(new StyleBundle("~/Content/css").Include(
18                       "~/Content/bootstrap.css",
19                       "~/Content/site.css"));
20         }
21     }  

其中的ScriptBundle和StyleBundle分別是用於管理js和css的類,這兩個類都是繼承了Bundle這個類!

它位於System.Web.Optimization程式集,如果想要用這個功能,記得添加引用喔!

那我們要怎麼使用這個呢?

現在假設在根目錄下麵有css和js兩個文件夾,裡面分別存放著Style1.css、Style2.css和js1.js、js2.js

下麵就來看看怎麼把它交於Bundle管理

1      bundles.Add(new ScriptBundle("~/bundles/js").Include(
2                     "~/js/js1.js",
3                     "~/js/js2.js"));
4       bundles.Add(new StyleBundle("~/bundles/css").Include(
5                     "~/css/Style1.css",
6                     "~/css/Style2.css"));  
 其中的“~/bundles/js”和"~/bundles/css"是虛擬路徑!  然後就是在頁面中使用(就是用我們剛纔的虛擬路徑)
1  @Styles.Render("~/bundles/css")
2  @Scripts.Render("~/bundles/js")  

是不是很方便呢!更多關於Bundle的內容可以參考

http://www.asp.net/mvc/overview/performance/bundling-and-minification

因為它不是我們今天的主要內容,只是拿來與Nancy中的靜態文件處理形成對比,便於我們的理解。

下麵就來看看Nancy中的靜態文件怎麼處理。

為了演示的方便,這裡僅使用css。

先看看具體的使用,然後再簡單分析其內部的實現。

一、新建一個空的asp.net應用程式

在這個應用程式中添加我們需要的引用,這裡可以根據前面介紹的,

按自己喜歡的方式、方法來添加Nancy相關的引用

二、建立Modules

老規矩:Modules文件夾、HomeModule.cs

 1     public class HomeModule : NancyModule
 2     {
 3         public HomeModule()
 4         {
 5             Get["/"] = _ =>
 6             {
 7                   return View["index"];
 8             };
 9 
10             Get["/default"] = _ =>
11             {
12                 return View["default"];
13             };
14 
15             Get["/custom"] = _ =>
16             {
17                 return View["custom"];
18             };
19 
20             Get["/other"] = _ =>
21             {
22                 return View["other"];
23             };
24 
25             Get["/sub"] = _ =>
26             {
27                 return View["sub"];
28             };
29         }
30     } 

三、新建content、assets、other三個文件夾,以及在assets文件夾下麵新建一個sub文件夾用於存放樣式表

四、分別添加一些簡單的樣式在這些文件夾中

content下麵的sytle.css內容如下

1 body {background-color:#00ffff;}
2 p {font-size:xx-large; }  

assets和other下麵的style.css內容如下

1 body {background-color:#00ffff;}
2 p {font-size:xx-large;color:#ff0000;}  

assets/sub下麵 的style.css內容如下

1 body {background-color:#808080;}
2 p {font-size:xx-large;color:#ff0000;}  

五、添加Views

老規矩:Views文件夾、Home文件夾

添加 index.html、default.html、custom.html、other.html、sub.html 五個頁面

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title>index</title>
 5     <meta charset="utf-8" />
 6 </head>
 7 <body>
 8     <a href="/default">page with default convention</a><br />
 9     <a href="/custom">page with custom convention</a><br />
10     <a href="/other">page without custom convention</a><br />
11     <a href="/sub">page sub</a>
12 </body>
13 </html>
index.html
 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title>default</title>
 5     <meta charset="utf-8" />
 6     <link href="../../content/style.css" rel="stylesheet" />
 7 </head>
 8 <body>
 9    <p>這是引用 /content/sytle.css 的頁面(預設的convention配置)</p>
10 </body>
11 </html>
default.html
 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title>custom</title>
 5     <meta charset="utf-8" />
 6     <link href="../../assets/style.css" rel="stylesheet" />
 7 </head>
 8 <body>
 9    <p>這是引用 /assets/style.css 的頁面(自定義Convention配置)</p>
10 </body>
11 </html>
custom.html
 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title>other</title>
 5     <meta charset="utf-8" />
 6     <link href="../../other/style.css" rel="stylesheet" />
 7 </head>
 8 <body>   
 9     <p>這是引用 /other/style.css 的頁面(沒有Convention配置)</p>
10 </body>
11 </html>
other.html
 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title>sub</title>
 5     <meta charset="utf-8" />
 6     <link href="../../assets/sub/style.css" rel="stylesheet" />
 7 </head>
 8 <body>
 9    <p>這是引用 /assets/sub/style.css 的頁面(自定義Convention配置,子文件夾測試)</p>
10 </body>
11 </html>
sub.html

六、在"引導程式"中配置Convention(至關重要的一步)

新建DemoBootstrapper.cs,使其繼承DefaultNancyBootstrapper並且override我們的ConfigureConventions

1     public class DemoBootstrapper : DefaultNancyBootstrapper
2     {
3         protected override void ConfigureConventions(NancyConventions nancyConventions)
4         {
5             base.ConfigureConventions(nancyConventions);
6             nancyConventions.StaticContentsConventions.Add(StaticContentConventionBuilder.AddDirectory("assets"));
7         }
8     }  

七、運行結果

八、結果分析與探討

1、default.html 用的樣式是在content下麵的,能正常載入樣式!

2、custom.html用的樣式是在assets下麵的,能正常載入樣式!

3、other.html用的樣式是在other下麵的,不能正常載入樣式!!

4、sub.html用的樣式是在assets/sub下麵的,能正常載入樣式!

很明顯,結果有點出乎我們的意料,我們在Convetion的配置中,只配置了一項!

就是對assets文件夾進行了處理。其他都沒有手動配置!

但是在content下麵的樣式是能夠正常顯示的!!而other下麵的是不能正常顯示的!!assets的子文件夾sub的樣式也正常顯示!!

這個給人貌似不是很合理的感覺。

看看Network的內容會發現other下麵的樣式表不是不能正常載入那麼簡單,而是直接給個404!!!

 

那我們就深入的去看看這裡面到底發生了什麼事吧!

fork一份Nancy的源碼,clone到本地,來看看個所以然。(其實上面的例子我就是在源碼上面添加的一個Demo)

首先看看我們今天的主題Conventions下麵的東西

其中從名字就可以看出跟我們今天的主題靜態文件,相關的就有7個!!

但這並不是我們的出發點,我們的出發點是下麵這個!

1     protected override void ConfigureConventions(NancyConventions nancyConventions)
2         {
3             base.ConfigureConventions(nancyConventions);
4             nancyConventions.StaticContentsConventions.Add(StaticContentConventionBuilder.AddDirectory("assets"));
5         }  

 

Convention的配置指引著我們要先去看看NancyConvetions這個類

在其構造方法中調用了 BuildDefaultConventions 這個方法

1         /// <summary>
2         /// Initializes a new instance of the <see cref="NancyConventions"/> class.
3         /// </summary>
4         public NancyConventions()
5         {
6             this.BuildDefaultConventions();
7         }    

這就很明顯的告訴我們,無論如何,它都會有預設的Conventions!!而且看了裡面的實現

會發現,預設的Convention還不僅僅是一個!!而是包含多個。這裡我們僅探討關於靜態文件的。

 1         private void BuildDefaultConventions()
 2         {
 3             var defaultConventions =
 4                 AppDomainAssemblyTypeScanner.TypesOf<IConvention>(ScanMode.OnlyNancy);
 5             this.conventions = defaultConventions
 6                 .Union(AppDomainAssemblyTypeScanner.TypesOf<IConvention>(ScanMode.ExcludeNancy))
 7                 .Select(t => (IConvention)Activator.CreateInstance(t));
 8             foreach (var convention in this.conventions)
 9             {
10                 convention.Initialise(this);
11             }
12         }  

現在我們就該去找關於靜態文件的預設Convetion

發現剛纔的7個相關中,有一個DefaultStaticContentsConventions

它實現了IConvention介面(Nancy中基本都是介面化編程,很Nice!!)。

其中的初始化方法中

1         public void Initialise(NancyConventions conventions)
2         {
3             conventions.StaticContentsConventions = new List<Func<NancyContext, string, Response>>
4             {
5                 StaticContentConventionBuilder.AddDirectory("Content")
6             };
7         }  

是不是跟我們自定義配置幾乎相差無幾!!我想看到AddDirectory的參數"Content",大家也應該都知道了

為什麼我們的content下麵的樣式,沒有配置都能正常載入(我去,它預設都是content,能不正常載入麽。。)

裡面的StaticContentConventionBuilder又是何方神聖呢?

這個是靜態基於目錄的幫助類

裡面有兩個主要的方法 AddDirectory和AddFile ,都是返回Func<NancyContext, string, Response>類型的東東。

看名字都已經知道大概實現了什麼東西,一個基於某個目錄,一個基於某個單獨的文件。

這裡需要註意一下這兩個方法的參數!

還有一些其他的東西是用於拼接目錄和處理Cache的。

把這幾個重要的類看了一下,是不是對這個靜態文件的預設配置也清晰了不少呢?

然後對自定義Convetion配置的理解也是類似的,所以這裡就不再累贅了。

從"引導程式"的ConfigureConventions中可以知道,無論我們自定義多少個Convetion,

都是要添加到StaticContentsConventions這個集合中的。

九、簡單總結

ConfigureConventions 與 BundleConfig 都是用於處理靜態文件的,有相同之處,也有各自的特點。

在項目開發過程中,我們可能會根據習慣把css、javascript這些靜態文件放在自己喜歡的位置,

但是在Nancy中這個的處理需要十分註意的是,只要我們沒有將css和javascript文件放在content中時,就一定要記得在Convention中進行配置!

否則頁面死活不是我們期待的那樣。。。。

所以我個人感覺這塊內容不是很友好,一旦不小心忘了配置,而且發現頁面樣式不對,首先想到的是不是樣式的路徑寫錯了

而不會直接考慮到Nancy的Convention配置這一層面。

為此,提醒各位使用Nancy的朋友,並建議各位:只要您的項目用到了靜態文件,請務必要override我們的ConfigureConventions !!

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Redis有兩種持久化的方式:快照(RDB文件)和追加式文件(AOF文件)RDB持久化方式是在一個特定的間隔保存某個時間點的一個數據快照。AOF(Append only file)持久化方式則會記錄每一個伺服器收到的寫操作。數據回覆時,這些記錄的操作會逐條執行從而重建出原來的數據。寫操作命令 記錄的...
  • 模塊剛到如圖所示~2016-01-26後三張是手機APP的截圖,前面是兩個ESP8266的硬體模塊,當然大家不應定要買兩個,自己焊錫一個USB轉TTL的串口就行了,有了下麵的底座我們就能方便的把ESP8266的AT固件的燒錄到晶元裡面了,同時模塊也接出來了TXD和RXD方便大家進行微控制器的通訊~板...
  • 今天把ef框架換成了dapper,資料庫使用的是mysql. 主鍵使用GUID,mysql資料庫中設置的為varchar(36). 使用dapper報錯,不能將string轉換為GUID,後來調試比對發現,mysql中要使用GUID,必須設置為char(36)不能設置為varchar(36).
  • foreach (DataColumn dt in _ds.Tables[0].Columns) { foreach (var str in _str2Array[0]) { if(dt.ColumnName.Trim() == str) { //DataTable刪除指定列 _table.Colu
  • 很多時候,為了提升性能,我們可以給資料庫訪問層做緩存。 以下幾步可以完成這個任務:1. 使用自定義的 XPObjectSpaceProvider1.1. 創建自定義的 XPObjectSpaceProvider 類,派生類中需要重寫CreateDataLayer 方法去創建一個 IDataLayer
  • C# 中的委托和事件 摘自:http://www.cnblogs.com/JimmyZhang/archive/2007/09/23/903360.html 引言 委托 和 事件在 .Net Framework中的應用非常廣泛,然而,較好地理解委托和事件對很多接觸C#時間不長的人來說並不容易。它們就
  • 之前做Opengl程式,用的的C#的SharpGL這個庫,裡面有各種奇怪綁定的函數,比如原型為: void glInterleavedArrays(uint format, int stride, void * pointer); 的函數被他綁定成: private static extern vo
  • 測試
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...