天天看點

Nancy之給我們的網站添加自定義圖示

原文: Nancy之給我們的網站添加自定義圖示

當我們在做一個網站時,可能經常會有這樣一個需求,要給我們做的網站添加一個自定義的圖示。

在Nancy中,預設是的下面這樣

Nancy之給我們的網站添加自定義圖示

一個妹子的頭像,其實也是挺好看的!!

那麼當我們想要替換這個預設的,應該要怎麼做呢?

下面就來看看具體的實作

首先,準備一張名為 favicon.ico或 favicon.png 圖檔

Nancy之給我們的網站添加自定義圖示

這裡有兩種實作方法提供參考

方法一:替換預設的圖示(IRootPathProvider的實作)

如果我們是使用預設的IRootPathProvider的實作,這個時候,我們直接添加圖檔在我們的項目根目錄即可

Nancy會去搜尋這個預設的RootPath的favicon資源,它找到的第一個就将會是我們網站的圖示。

效果如下:

Nancy之給我們的網站添加自定義圖示

有時候,預設的不一定是最好的,是以我們可以

自己去實作IRootPathProvider這個接口,但一個項目中,隻能有一個實作(除了預設的)

具體如下

1     public class CustomRootPathProvider : IRootPathProvider
2     {
3         public string GetRootPath()
4         {     
5             return AppDomain.CurrentDomain.GetData(".appPath").ToString();
6         }
7     }        

其中,GetRootPath傳回的是絕對路徑!!

這個路徑可以用你能想到的任何方式得到!

然後,我們需要在“引導程式”中做點事

1      protected override IRootPathProvider RootPathProvider
2         {
3             get { return new CustomRootPathProvider(); }
4         }       

這樣做是比較保險的一種做法(不需要特地将我們的圖檔資源設定為嵌入的資源) 

方法二:使用嵌入的圖示(Override FavIcon)

這種方法需要我們去重寫 FacIcon這個方法

1     protected override byte[] FavIcon
 2         {
 3             get { return this.favicon ?? (this.favicon = LoadFavIcon()); }       
 4         }
 5         private byte[] LoadFavIcon()
 6         {         
 7             using (var resourceStream = GetType().Assembly.GetManifestResourceStream("NancyFavIconDemo.favicon.ico"))
 8             {
 9                 var tempFavicon = new byte[resourceStream.Length];
10                 resourceStream.Read(tempFavicon, 0, (int)resourceStream.Length);
11                 return tempFavicon;
12             }
13         }        

其中,GetMainifestResourceStream的參數是“程式集名稱.資源名稱”(NancyFavIconDemo是我這個Demo的程式集名稱,favicon.ico是我在根目錄的一個圖檔)

還有重要的一步是

将我們的圖檔屬性中的Build Action設定為 Embedded Resource(嵌入的資源)

Nancy之給我們的網站添加自定義圖示

具體原因我們可以參考

Assembly.GetManifestResourceStream Method (String)

裡面的Remark

A manifest resource is a resource (such as an image file) that is embedded in the assembly at compile time. 

此時,我們同樣可以看到相同的效果

Nancy之給我們的網站添加自定義圖示

如果 我們沒有設定為嵌入的資源,那麼我們的resourceStream對象将一直為空

Nancy之給我們的網站添加自定義圖示

下面我們來看看Nancy這一塊内容的内部實作

關于favicon的實作就是在FavIconApplicationStartup.cs裡面

Nancy之給我們的網站添加自定義圖示

來看看它的描述

Nancy之給我們的網站添加自定義圖示

就像前面說的,它會去找favicon,找到就用找到的,沒找到就用預設的。

裡面有一個帶IRootPathProvider參數構造函數,可以簡單了解為指定要搜尋的範圍。

1         /// <summary>
2         /// Initializes a new instance of the <see cref="FavIconApplicationStartup"/> class, with the
3         /// provided <see cref="IRootPathProvider"/> instance.
4         /// </summary>
5         /// <param name="rootPathProvider">The <see cref="IRootPathProvider"/> that should be used to scan for a favicon.</param>
6         public FavIconApplicationStartup(IRootPathProvider rootPathProvider)
7         {
8             FavIconApplicationStartup.rootPathProvider = rootPathProvider;
9         }      

下面是預設的圖示實作方法,我們override的實作和它的基本一緻!!

1         private static byte[] ExtractDefaultIcon()
 2         {
 3             var resourceStream =
 4                 typeof(INancyEngine).Assembly.GetManifestResourceStream("Nancy.favicon.ico");
 5 
 6             if (resourceStream == null)
 7             {
 8                 return null;
 9             }
10 
11             var result =
12                 new byte[resourceStream.Length];
13 
14             resourceStream.Read(result, 0, (int)resourceStream.Length);
15 
16             return result;
17         }          

預設圖示在ErrorPipeline.cs和FormatterExtensions.cs之間(不細心去看,壓根就看不見)

Nancy之給我們的網站添加自定義圖示

裡面還有一個“搜尋”圖示的方法

1          private static byte[] LocateIconOnFileSystem()
 2         {
 3             if (rootPathProvider == null)
 4             {
 5                 return null;
 6             }
 7 
 8             var extensions = new[] { "ico", "png" };
 9 
10             var locatedFavIcon = extensions.SelectMany(EnumerateFiles).FirstOrDefault();
11             if (locatedFavIcon == null)
12             {
13                 return null;
14             }
15 
16             try
17             {
18                 return File.ReadAllBytes(locatedFavIcon);
19             }
20             catch (Exception e)
21             {
22                 if (!StaticConfiguration.DisableErrorTraces)
23                 {
24                     throw new InvalidDataException("Unable to load favicon", e);
25                 }
26 
27                 return null;
28             }
29         }      

我們可以發現,我們用的字尾可以是.ico和.png。 

繼續閱讀