iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 5
2
Modern Web

菜鳥練等區-ASP.Net Core MVC進化之路系列 第 5

[鐵人賽Day05] - 靜態檔案(Static Files)

ASP.Net MVC5中,
對於靜態檔案的存取並沒有特別的規範。
而在ASP.Net Core裡,
對於靜態檔案存取有特定的限制,
這樣的設計也有助於安全性的提升。

同步發表於個人點部落 - [鐵人賽Day05] ASP.Net Core MVC 進化之路 - 靜態檔案(Static Files)

靜態檔案泛指瀏覽器在呈現完整畫面時所需要的資源檔案,
常見有的.html.js.css.jpg.png等。

ASP.Net Core 中,
將靜態檔案預設存放於wwwroot的目錄中,
2.1版會自動將UseStaticFiles中介層加入Startup裡,
透過調整UseStaticFiles呼叫的順序,
可以避免經過不需要的Middleware所造成的浪費。

我們試著在wwwroot裡新增一個index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    index.html in wwwroot directory.
</body>
</html>

輸出結果如下:

假設我想存取其他目錄的靜態檔案呢?
我們在專案目錄下新增一個MyHtmlFiles目錄,
並在MyHtmlFiles底下新增一個mypage.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    mypage.html in MyHtmlFiles Directory.
</body>
</html>

完成後於瀏覽器進行測試,
會發現找不到檔案。

嘗試加入目錄名稱後一樣找不到。

若要允取瀏覽器(Client)存取指定的目錄下的檔案(MyHtmlFiles),
可於Startup中的Configure做設定。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseStaticFiles();
    app.UseStaticFiles(new StaticFileOptions
    {
        FileProvider = new PhysicalFileProvider(
        Path.Combine(Directory.GetCurrentDirectory(), "MyHtmlFiles")),
        RequestPath = "/myfiles"
    });
}

透過自訂請求路徑(/myfiles)存取MyHtmlFiles的目錄,
可以防止伺服器檔案路徑洩漏問題,

調整後再編譯執行一次。

設定預設檔案

我們可以使用UseDefaultFiles設定預設路由

官方預設將下列幾種當作預設名稱

  • default.htm
  • default.html
  • index.htm
  • index.html

我們也可以自訂預設名稱。

DefaultFilesOptions options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();

option.DefaultFileNames.Clear()會將預設的檔案名稱移除,
在這邊有一點要注意的是預設名稱只能有一個,
因此註冊的順序會影響路由的結果。
如果在new DefaultFilesOption時沒有Clear
加入自訂檔名時會附加到原本預設名稱集合後(如下圖)。

預設檔名在mapping時只要找到第一個符合的就會直接返回,
假設我們在wwwroot底下新增一個mydefault.html

接著修改Startup的內容。

DefaultFilesOptions options = new DefaultFilesOptions();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();

開啟預設路徑會發現顯示的是index.html的內容。

我們暫時將wwwroot/index.html重新命名為index1.html
再執行一次。

所以如果要針對特定目錄設定預設檔名,
建議將DefaultFileNames重設會比較好。

官方文件上特別提到,

UseDefaultFiles實際上是用URL rewriter幫我們做路由覆寫的動作,
但這不代表使用預設檔案就具有存取該檔案目錄的權限。

如果想要針對wwwroot外的目錄設定預設檔案,
則要另外進行設定。

app.UseDefaultFiles(new DefaultFilesOptions()
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(Directory.GetCurrentDirectory(), "MyHtmlFiles")),
    RequestPath = new PathString("/myfiles")
});
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(Directory.GetCurrentDirectory(), "MyHtmlFiles")),
    RequestPath = "/myfiles"
});

關於靜態的檔案就記錄到這邊。

參考

https://docs.microsoft.com/zh-tw/aspnet/core/fundamentals/static-files?view=aspnetcore-2.1&tabs=aspnetcore2x


上一篇
[鐵人賽Day04] - 淺談Middleware
下一篇
[鐵人賽Day06] - 路由(Route)
系列文
菜鳥練等區-ASP.Net Core MVC進化之路30

1 則留言

1
not
iT邦新手 5 級 ‧ 2018-12-31 00:28:21

您好,跟著您的教學,做到這篇卡關了

在iis express的環境下,要做這一段的時候,會顯示缺少套件
app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider( Path.Combine(Directory.GetCurrentDirectory(), "MyHtmlFiles")), RequestPath = "/myfiles" });
用VisualStudio自動生成後,會引用這兩個套件
using System.IO; using Microsoft.Extensions.FileProviders;
但實際執行時,網頁還沒開出來,就會顯示找不到資料夾的錯誤訊息
System.IO.DirectoryNotFoundException: 'C:\Program Files\IIS Express\MyHtmlFiles'

https://ithelp.ithome.com.tw/upload/images/20181231/20107416Kb3Ged7PYu.png

不知道有什麼方法可以解決,還是只能用在真正的IIS上才行呢?

您好,想請問IIS Express是否有安裝對應的Asp.Net Core Module呢?

我要留言

立即登入留言