.NET Core开发实战课程备忘(15) -- 静态文件中间件:前后端分离开发合并部署骚操作

静态文件中间件的能力

  • 支持指定相对路径
  • 支持目录浏览
  • 支持设置默认文档
  • 支持多目录映射

代码实现

创建项目

创建名字为StaticFilesDemoASP.NET Core项目,类型为API

创建测试用的静态文件

在根目录创建wwwroot文件夹,参照下面结构进行对应文件创建:

1
2
3
4
5
6
wwwroot
|-- app.js
|-- index.html
|-- a
|-- a.js
|-- index.html

具体代码如下:

/wwwroot/index.html

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>静态首页</title>
<script src="/app.js"></script>
</head>
<body>
<h1>这是静态首页 wwwroot/index.html</h1>
</body>
</html>

/wwwroot/app.js

1
alert("这是/index.html")

/wwwroot/a/index.html

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="a.js"></script>
</head>
<body>
<h1>这是/a/index.html</h1>
</body>
</html>

/wwwroot/a/a.js

1
alert("这是/a/index.html")

默认静态文件中间件

Startup.Configure中,将以下代码添加到app.UseHttpsRedirection();下一行

1
app.UseStaticFiles();

运行项目访问https://localhost:5001/index.htmlhttps://localhost:5001/a/index.html可看到静态页面信息

设置默认文件为index.html

能起到的效果如下:

https://localhost:5001 = https://localhost:5001/index.html

https://localhost:5001/a = https://localhost:5001/a/index.html

app.UseStaticFiles();前面添加以下代码即可:

1
app.UseDefaultFiles();

运行项目访问https://localhost:5001https://localhost:5001/a可看到静态页面信息

支持目录浏览

注释掉默认文件的那个中间件,添加目录浏览的中间件,代码如下:

1
app.UseDirectoryBrowser();

然后在Startup.ConfigureServices配置目录浏览的服务,代码如下:

1
services.AddDirectoryBrowser();

运行项目访问https://localhost:5001,可以看到wwwroot的目录结构

多目录映射

当文件支持存在放wwwroot这个文件夹的时候,可以使用静态文件中间件的重载来映射其他文件夹,注释掉上一步的代码,将Startup.Configure修改如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "file"))
});

app.UseRouting();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}

在项目根目录创建file文件夹,在里面创建个file_page.html文件,随便写点东西,运行项目,访问https://localhost:5001/file_page.html,可以看到静态页内容。注意,如果出现同名文件,则先注册的路径优先权更高,如果需要在访问指定文件夹有指定url地址,可以使用StaticFileOptions对象的RequestPath属性,假设这里的RequestPath="/myfiles",则说明要想访问file文件夹的内容,路径前面得加上myfiles,例如https://localhost:5001/myfiles/file_page.html

功能实现

有这样一个需求,接口里所有接口的路由都由api开始,即/api/xxx,静态文件放在默认的wwwroot文件夹中,如果访问的地址不是接口,同时也找不到对应的静态文件,则重写到/index.html页面,具体代码如下:

修改WeatherForecastController,将原本的[Route("[controller]")]修改为[Route("/api/[controller]")]

修改Startup.Configure方法,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.MapWhen(context =>
{
return !context.Request.Path.Value.StartsWith("/api");
}, appBuilder =>
{
var option = new RewriteOptions();
option.AddRewrite(regex: ".*", replacement: "/index.html", skipRemainingRules: true);
appBuilder.UseRewriter(option);
appBuilder.UseStaticFiles();
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}

运行项目,访问https://localhost:5001/api/WeatherForecast,可以看到正常返回接口信息,访问https://localhost:5001/a/index.html可以看到正常访问到/a/index.html文件内容,访问https://localhost:5001/order/get则会返回/index.html文件内容