AspNetCore(三)-靜態(tài)文件

1批狐、簡(jiǎn)介

當(dāng)我們需要訪問一個(gè)文件或者圖片的,其實(shí)是沒必要經(jīng)過Mvc中間件的處理扇售,完全可以自定義一個(gè)中間件處理,同樣微軟也提供了很多與靜態(tài)文件相關(guān)的中間件。
首先在.NetCore中wwwroot是默認(rèn)的靜態(tài)文件夾承冰。如果想要改變他,需要在Program類中做修改:

// 3.1版本
public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    // 設(shè)置靜態(tài)文件夾為根目錄下的staticfile文件夾
                    webBuilder.UseWebRoot("staticfile");
                    webBuilder.UseStartup<Startup>();
                });

2华弓、UseDirectoryBrowser()中間件

利用UseDirectoryBrowser()實(shí)現(xiàn)目錄瀏覽功能:
首先我們?cè)趙wroot中創(chuàng)建一個(gè)目錄images,然后在
UseDirectoryBrowser()中間件,可以實(shí)現(xiàn)目錄瀏覽的功能困乒,但是在使用該功能之前是需要注入服務(wù)的因此:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            // 注入目錄瀏覽服務(wù)
            services.AddDirectoryBrowser();
        }

使用中間件:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            // 使用目錄瀏覽中間件
            app.UseDirectoryBrowser();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }

這樣啟動(dòng)就可以看到我wwwroot目錄下的文件夾:


瀏覽目錄

如果我只想顯示wwwroot目錄下的images文件夾該怎么辦呢寂屏?
第一種方式:在Program中指定靜態(tài)文件夾目錄(簡(jiǎn)介中)
第二種方式:UseDirectoryBrowser()也提供了參數(shù),來看一下參數(shù):

  • FileProvider: 文件提供者,一般給絕對(duì)路徑(防止在不同系統(tǒng)出錯(cuò))顶燕。
  • RequestPath: 提供一個(gè)虛擬路徑 (假如賦值為"/files")就需要訪問該url凑保。
  • Formatter: 這個(gè)參數(shù)可以自定義顯示的頁面(布局)請(qǐng)求頭等信息。
    使用一下前兩個(gè)參數(shù):
app.UseDirectoryBrowser(new DirectoryBrowserOptions
            {
                // 只展示 wwwroot/images 下的文件
                FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
                // 給一個(gè)虛擬路徑
                RequestPath = "/staticfiles"
            });

此時(shí)啟動(dòng)程序輸入輸入:http://localhost:5000/staticfiles/ 會(huì)看到改目錄下的文件:

http://localhost:5000/staticfiles/

自定義顯示頁面:
新創(chuàng)建一個(gè)類繼承IDirectoryFormatter接口:
只用實(shí)現(xiàn)GenerateContentAsync方法即可,傳遞了兩個(gè)參數(shù)一個(gè)是HttpContext,另一個(gè)是IEnumerable存放的是改目錄下的文件信息,給了這倆參數(shù)涌攻,返回什么信息都是你自己說了算欧引。
例如這里只展示文件名(當(dāng)然你可以定義一個(gè)更好看的頁面):

    public class StaticFilesDirectoryFormatter : IDirectoryFormatter
    {
        public async Task GenerateContentAsync(HttpContext context, IEnumerable<IFileInfo> contents)
        {
            // 指定返回的是一個(gè)html 
            // context.Response.ContentType = "text/html;charset=utf-8";
            foreach (var item in contents)
            {
               await context.Response.WriteAsync(item.Name);
            }
        }
    }

并且在使用該中間件的地方給Formatter參數(shù)賦值就可以了:

app.UseDirectoryBrowser(new DirectoryBrowserOptions
            {
                FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
                RequestPath = "/staticfiles",
                // 默認(rèn)定義的頁面是在HtmlDirectoryFormatter(HtmlEncoder.Default)中。
                Formatter = new StaticFilesDirectoryFormatter()
            });

啟動(dòng)查看頁面:


自定義頁面

由于自定義頁面很low,所以我就使用默認(rèn)的把恳谎。
使用默認(rèn)的點(diǎn)擊一下圖片你會(huì)發(fā)現(xiàn)是404頁面芝此,沒有找到該文件。
這是因?yàn)橹唤o了瀏覽目錄的權(quán)限因痛,如果還需要可以瀏覽圖片婚苹,需要使用UseStaticFiles()中間件。

3鸵膏、UseStaticFiles()中間件

當(dāng)我們添加添加UseStaticFiles()中間件后膊升,訪問發(fā)現(xiàn)還是404,那是因?yàn)槟J(rèn)還是在wwwroot中查找該文件,自然沒有找到谭企,所以我們需要和UseDirectoryBrowser()中配置一樣廓译。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseDirectoryBrowser(new DirectoryBrowserOptions
            {
                FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
                RequestPath = "/staticfiles",
                // 默認(rèn)定義的頁面是在HtmlDirectoryFormatter(HtmlEncoder.Default)中。
                // Formatter = new StaticFilesDirectoryFormatter()
            });
            app.UseStaticFiles(new StaticFileOptions
            {
                RequestPath = "/staticfiles",
                FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
            });
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }

你會(huì)發(fā)現(xiàn)你可以預(yù)覽圖片了债查。
還有其他的屬性:

  • ContentTypeProvider:文件提供器
  • OnPrepareResponse:訪問文件走的方法,可以做一些處理
  • DefaultContentType:設(shè)置默認(rèn)的MIME訪問類型
  • ServeUnknownFileTypes:bool值非区,也就是不認(rèn)可的文件類型提不提供服務(wù)(比如存在.log文件,如果不設(shè)置為true,就無法訪問)盹廷,默認(rèn)false
  • httpsCompression:控制HTTPS請(qǐng)求的響應(yīng)壓縮征绸。
    在這里只對(duì)ContentTypeProvider和OnPrepareResponse做一下示例:
    通過OnPrepareResponse對(duì)jpg圖片進(jìn)行緩存,其他則不進(jìn)行緩存:
            app.UseStaticFiles(new StaticFileOptions
            {
                ServeUnknownFileTypes = true, 
                RequestPath = "/staticfiles",
                FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
                OnPrepareResponse = opr => {
                    string extion = Path.GetExtension(HttpUtility.UrlDecode(opr.Context.Request.Path));
                    if (extion == ".jpg")
                    {
                        // 設(shè)置緩存
                        opr.Context.Response.Headers.Add("Cache-Control", "public,max-age=600");
                        // 也可以進(jìn)行下載 
                        // opr.Context.Response.ContentType = "application/octet-stream";
                    }
                }
            }) ;
通過ContentTypeProvider移除對(duì)png圖片的訪問權(quán)限(當(dāng)我們使用ContentTypeProvider移除一中文件訪問權(quán)的話,需要把ServeUnknownFileTypes設(shè)置為false,否者不起作用),對(duì)log結(jié)尾的進(jìn)行下載俄占。

            var fileProvider = new FileExtensionContentTypeProvider();
            fileProvider.Mappings.Remove(".png");
            fileProvider.Mappings[".log"] = "application/octet-stream";
            app.UseStaticFiles(new StaticFileOptions
            {
                ContentTypeProvider = fileProvider,
                //ServeUnknownFileTypes = true, 
                RequestPath = "/staticfiles",
                FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
                OnPrepareResponse = opr => {
                    string extion = Path.GetExtension(HttpUtility.UrlDecode(opr.Context.Request.Path));
                    if (extion == ".jpg")
                    {
                        // 設(shè)置緩存
                        opr.Context.Response.Headers.Add("Cache-Control", "public,max-age=600");
                        // 也可以進(jìn)行下載 
                        // opr.Context.Response.ContentType = "application/octet-stream";
                    }
                },
            });

4管怠、UseDefaultFiles()中間件

該中間件可以在啟動(dòng)的時(shí)候顯示html頁面,當(dāng)然也可以給與一個(gè)虛擬路徑缸榄。
UseDefaultFiles()中間件的使用需要在UseStaticFiles()之前,UseDefaultFiles()中間件是嘗試去尋找默認(rèn)文件,
而UseDefaultFiles()沒有尋找到是會(huì)報(bào)錯(cuò)404的渤弛。并且UseDefaultFiles中的參數(shù)有:

  • FileProvider:文件的路徑
  • RequestPath:虛擬路徑
  • DefaultFileNames:是一個(gè)數(shù)組,本身默認(rèn)的文件有defalt.html,defalt.htm,index.html,index.htm,如果你是其他名字需要自己添加碰凶。
    其中FileProvider和RequestPath屬性是需要和UseStaticFiles()的屬性保持一致暮芭,否者就會(huì)找不到文件。
    例如:
            app.UseDefaultFiles(new DefaultFilesOptions {
                FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
                RequestPath = "/staticfiles",
                DefaultFileNames = new List<string> { "aaa.html" }
            });
            app.UseStaticFiles(new StaticFileOptions {
                FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
                RequestPath = "/staticfiles",
            });

此時(shí)訪問/staticfiles頁面如果有aaa.html頁面欲低,就會(huì)顯示html頁面辕宏,這里就不再演示。
綜上上面的三個(gè)中間件,如果我需要改修一個(gè)RequestPath屬性砾莱,那么其他都要修改瑞筐,并且是重復(fù)的代碼。
于是就有了UseFileServer()中間件腊瑟。這一個(gè)就夠了聚假。

5、UseFileServer()中間件

使用這一個(gè)中間件就相當(dāng)于使用了上面三個(gè)中間件闰非,當(dāng)然功能可就就少一些膘格。

  • EnableDefaultFiles:bool值 是否開啟默認(rèn)文件訪問
  • EnableDirectoryBrowsing:bool值 是否開啟瀏覽文件夾
  • FileProvider:路徑
  • RequestPath:虛擬路徑
    例如:
            app.UseFileServer(new FileServerOptions
            {
                EnableDefaultFiles = true,
                EnableDirectoryBrowsing = true,
                FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
                RequestPath = "/staticfiles"
            });
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市财松,隨后出現(xiàn)的幾起案子瘪贱,更是在濱河造成了極大的恐慌,老刑警劉巖辆毡,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件菜秦,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡舶掖,警方通過查閱死者的電腦和手機(jī)球昨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來眨攘,“玉大人主慰,你說我怎么就攤上這事∑谌” “怎么了河哑?”我有些...
    開封第一講書人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)龟虎。 經(jīng)常有香客問我璃谨,道長(zhǎng),這世上最難降的妖魔是什么鲤妥? 我笑而不...
    開封第一講書人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任佳吞,我火速辦了婚禮,結(jié)果婚禮上棉安,老公的妹妹穿的比我還像新娘底扳。我一直安慰自己,他們只是感情好贡耽,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開白布衷模。 她就那樣靜靜地躺著鹊汛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪阱冶。 梳的紋絲不亂的頭發(fā)上刁憋,一...
    開封第一講書人閱讀 52,158評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音木蹬,去河邊找鬼至耻。 笑死,一個(gè)胖子當(dāng)著我的面吹牛镊叁,可吹牛的內(nèi)容都是我干的尘颓。 我是一名探鬼主播,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼晦譬,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼疤苹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起敛腌,我...
    開封第一講書人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤痰催,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后迎瞧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夸溶,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年凶硅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了缝裁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡足绅,死狀恐怖捷绑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情氢妈,我是刑警寧澤粹污,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站首量,受9級(jí)特大地震影響壮吩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜加缘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一鸭叙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拣宏,春花似錦沈贝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嗡善。三九已至,卻和暖如春学歧,著一層夾襖步出監(jiān)牢的瞬間滤奈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工撩满, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人绅你。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓伺帘,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親忌锯。 傳聞我的和親對(duì)象是個(gè)殘疾皇子伪嫁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容