- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章解析如何利用一个ASP.NET Core应用来发布静态文件由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
虽然ASP.NET Core是一款“动态”的Web服务端框架,但是在很多情况下都需要处理针对静态文件的请求,最为常见的就是这对JavaScript脚本文件、CSS样式文件和图片文件的请求。针对不同格式的静态文件请求的处理,ASP.NET Core为我们提供了三个中间件,它们将是本系列文章论述的重点。不过在针对对它们展开介绍之前,我们照理通过一些简单的实例来体验一下如何在一个ASP.NET Core应用中发布静态文件.
目录 。
1、以Web的形式读取文件 。
2、浏览目录内容 。
3、显示默认页面 。
4、映射媒体类型 。
1、以Web的形式读取文件 。
我们创建的演示实例是一个简单的ASP.NET Core控制台应用,它具有如下图所示的项目结构。我们可以看到在默认作为WebRoot的目录(wwwroot)下,我们将JavaScript脚本文件、CSS样式文件和图片文件存放到对应的子目录(js、css和img)下,我们将把这个目录的所有文件以Web的形式发布出来,客户端可以访问相应的URL来获取这些文件.
针对静态文件的请求是通过一个名为StaticFileMiddleware的中间件来实现的,这个中间件类型定义在NuGet包“Microsoft.AspNetCore.StaticFiles”中,所以我们需要预先按照这个NuGet包。整个应用只包含如下所示的这几行代码,StaticFileMiddleware这个中间件的注册是通过调用ApplicationBuilder的扩展方法UseStaticFiles来完成的.
1
2
3
4
5
6
7
8
9
10
11
12
|
public
class
Program
{
public
static
void
Main()
{
new
WebHostBuilder()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseKestrel()
.Configure(app => app.UseStaticFiles())
.Build()
.Run();
}
}
|
除了注册必需的StaticFileMiddleware中间件之外,我们还调用了WebHostBuilder的UseContentRoot方法将当前项目的根目录作为ContentRoot目录。我们知道ASP.NET Core应用具有两个重要的根目录,它们分别是ContentRoot和WebRoot,后者也是对外发布的静态文件默认使用的根目录。由于WebRoot目录的默认路径就是“{contentroot}/wwwroot”,所示上面这段程序就是将项目中的这个wwwroot目录下的所有静态文件发布出来.
当这个程序运行之后,我们就可以通过向对应URL发送HTTP请求的方式来获取某个的文件,这个URL由文件相当于wwwroot目录的路径来决定。比如JPG文件“~/wwwroot/img/dophin1.jpg”对应的URL为“http:// 。
localhost:5000/img/dophin1.jpg”。我们直接利用浏览器访问这个URL,目标图片会直接显示出来.
上面我们通过一个简单的实例将WebRoot所在目录下的所有静态文件直接发布出来。如果我们需要发布的静态文件存储在其他目录下呢?依旧是演示的这个应用,现在我们将一些文档存储在如下图所示的“~/doc/”目录下并以Web的形式发布出来,我们的程序又该如何编写呢?
我们知道ASP.NET Core应用大部分情况下都是利用一个FileProvider对象来读取文件的,它在处理针对静态文件的请求是也不例外。对于我们调用ApplicationBuilder的扩展方法UseStaticFiles方法注册的这个类型为StaticFileMiddleware的中间件,其内部具有一个FileProvider和请求路径的映射关系。如果调用UseStaticFiles方法没有指定任何的参数,那么这个映射关系的请求路径就是应用的基地址(PathBase),而FileProvider自然就是指向WebRoot目录的PhysicalFileProvider.
上述的这个需求可以通过显式注册这个映射的方式来实现,为此我们在现有程序的基础上额外添加了一次针对UseStaticFiles方法的调用,并通过指定的参数(是一个StaticFileOptions对象)显式指定了采用的FileProvider(针对“~/doc/”的PhysicalFileProvider)和请求路径(“/documents”).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public
class
Program
{
public
static
void
Main()
{
string
contentRoot = Directory.GetCurrentDirectory();
new
WebHostBuilder()
.UseContentRoot(contentRoot)
.UseKestrel()
.Configure(app => app
.UseStaticFiles()
.UseStaticFiles(
new
StaticFileOptions {
FileProvider =
new
PhysicalFileProvider(Path.Combine(contentRoot,
"doc"
)),
RequestPath =
"/documents"
}))
.Build()
.Run();
}
}
|
按照上面这段程序指定的映射关系,对于存储在“~/doc/”目录下的这个PDF文件(“checklist.pdf”),发布在Web上的URL为“http://localhost:5000/documents/checklist.pdf”。当我们在浏览器上请求这个地址时,该PDF文件的内容将会按照如下图所示的形式显示在浏览器上.
2、浏览目录内容 。
注册的StaticFileMiddleware中间件只会处理针对某个具体静态文件的额请求,如果我们向针对某个目录的URL发送HTTP请求(比如“http://localhost:5000/img/”),得到的将是一个状态为404的响应。不过我们可以通过注册另一个名为DirectoryBrowserMiddleware的中间件来显示请求目录的内容。具体来说,这个中间件会返回一个HTML页面,请求目录下的所有文件将以表格的形式包含在这个页面中。对于我们演示的这个应用来说,我们可以按照如下的方式调用UseDirectoryBrowser方法来注册这个DirectoryBrowserMiddleware中间件.
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
|
public
class
Program
{
public
static
void
Main()
{
string
contentRoot = Directory.GetCurrentDirectory();
IFileProvider fileProvider =
new
PhysicalFileProvider(
Path.Combine(contentRoot,
"doc"
));
new
WebHostBuilder()
.UseContentRoot(contentRoot)
.UseKestrel()
.Configure(app => app
.UseStaticFiles()
.UseStaticFiles(
new
StaticFileOptions {
FileProvider = fileProvider,
RequestPath =
"/documents"
})
.UseDirectoryBrowser()
.UseDirectoryBrowser(
new
DirectoryBrowserOptions {
FileProvider = fileProvider,
RequestPath =
"/documents"
}))
.Build()
.Run();
}
}
|
当上面这个应用启动之后,如果我们利用浏览器向针对某个目录的URL(比如“http://localhost:5000/”或者“http://localhost:5000/img/”),目标目录的内容(包括子目录和文件)将会以下图所示的形式显示在一个表格中。不仅仅如此,子目录和文件均会显示为链接,指向目标目录或者文件的URL.
3、显示默认页面 。
从安全的角度来讲,利用注册的UseDirectoryBrowser中间件显示一个目录浏览页面会将整个目标目录的接口和所有文件全部暴露出来,所以这个中间件需要根据自身的安全策略谨慎使用。对于针对目录的请求,另一种更为常用的响应策略就是显示一个保存在这个目录下的默认页面。按照约定,作为默认页面的文件一般采用如下四种命名方式:default.htm、default.html、index.htm或者index.html。针对目标目录下默认页面的呈现实现在一个名为DefaultFilesMiddleware的中间件中,我们演示的这个应用可以按照如下的方式调用UseDefaultFiles方法来注册这个中间件.
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
27
28
29
30
31
|
public
class
Program
{
public
static
void
Main()
{
string
contentRoot = Directory.GetCurrentDirectory();
IFileProvider fileProvider =
new
PhysicalFileProvider(Path.Combine(contentRoot,
"doc"
));
new
WebHostBuilder()
.UseContentRoot(contentRoot)
.UseKestrel()
.Configure(app => app
.UseDefaultFiles()
.UseDefaultFiles(
new
DefaultFilesOptions{
RequestPath =
"/documents"
,
FileProvider = fileProvider,
})
.UseStaticFiles()
.UseStaticFiles(
new
StaticFileOptions
{
FileProvider = fileProvider,
RequestPath =
"/documents"
})
.UseDirectoryBrowser()
.UseDirectoryBrowser(
new
DirectoryBrowserOptions
{
FileProvider = fileProvider,
RequestPath =
"/documents"
}))
.Build()
.Run();
}
}
|
现在我们在“~/wwwroot/img/”目录下创建一个名为index.htm的默认页面,现在利用浏览器访问这个目录对应的URL(“http://localhost:5000/img/”),显示就时这个页面的内容.
我们必须在注册StaticFileMiddleware和DirectoryBrowserMiddleware之前注册DefaultFilesMiddleware,否则它起不了任何作用。由于DirectoryBrowserMiddleware和DefaultFilesMiddleware这两个中间件处理的均是针对目录的请求,如果DirectoryBrowserMiddleware先被注册,那么显示的总是目录的内容。若DefaultFilesMiddleware先被注册,在默认页面不存在情况下回显示目录的内容。至于为什么要先于StaticFileMiddleware之前注册DefaultFilesMiddleware,则是因为后者是通过采用URL重写的方式实现的,也就是说这个中间件会将针对目录的请求改写成针对默认页面的请求,而最终针对默认页面的请求还得依赖StaticFileMiddleware完成.
DefaultFilesMiddleware中间件在默认情况下总是以约定的名称(default.htm、default.html、index.htm或者index.html)在当前请求的目录下定位默认页面。如果我们希望作为默认页面的文件不能按照这样的约定命名(比如readme.htm),我们需要按照如下的方式显式指定默认页面的文件名.
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
27
28
29
30
31
32
33
34
|
public
class
Program
{
public
static
void
Main()
{
string
contentRoot = Directory.GetCurrentDirectory();
IFileProvider fileProvider =
new
PhysicalFileProvider(Path.Combine(contentRoot,
"doc"
));
DefaultFilesOptions options1 =
new
DefaultFilesOptions();
DefaultFilesOptions options2 =
new
DefaultFilesOptions{
RequestPath =
"/documents"
,
FileProvider = fileProvider
};
options1.DefaultFileNames.Add(
"readme.htm"
);
options2.DefaultFileNames.Add(
"readme.htm"
);
new
WebHostBuilder()
.UseContentRoot(contentRoot)
.UseKestrel()
.Configure(app => app
.UseDefaultFiles(options1)
.UseDefaultFiles(options2)
.UseStaticFiles()
.UseStaticFiles(
new
StaticFileOptions{
FileProvider = fileProvider,
RequestPath =
"/documents"
})
.UseDirectoryBrowser()
.UseDirectoryBrowser(
new
DirectoryBrowserOptions{
FileProvider = fileProvider,
RequestPath =
"/documents"
}))
.Build()
.Run();
}
}
|
4、映射媒体类型 。
通过上面演示的实例可以看出,浏览器能够正确的将请求的目标文件的内容正常的呈现出来。对HTTP协议具有基本了解的人都应该知道,响应的文件能够在支持的浏览器上呈现具有一个基本的前提,那就是响应消息通过Content-Type报头携带的媒体类型必须与内容一致。我们的实例演示了针对两种类型文件的请求,一种是JPG文件,另一种是PDF文件,对应的媒体类型分别是“image/jpg”和“application/pdf”,那么StaticFileMiddleware是如何正确解析出正确的媒体类型的呢?
StaticFileMiddleware针对媒体类型的解析是通过一个名为ContentTypeProvider的对象来实现的,而默认使用的则是一个FileExtensionContentTypeProvider对象。顾名思义,FileExtensionContentTypeProvider是根据文件的扩展命名来解析媒体类型的。FileExtensionContentTypeProvider内部预定了数百种常用文件扩展名与对应媒体类型之间的映射关系,所以如果我们发布的静态文件具有标准的扩展名,StaticFileMiddleware就能为对应的响应赋予正确的媒体类型.
那么如果某个文件的扩展名没有在这个预定义的映射之中,或者我们需要某个预定义的扩展名匹配不同的媒体类型,我们应该如何解决呢?还是针对我们演示的这个实例,想在我将“~/wwwroot/img/ dophin1.jpg”这个文件的扩展名改成“.img”,毫无疑问StaticFileMiddleware将能为针对该文件的请求解析出正确媒体类型。这个问题具有若干不同的解决方案,第一种方案就是让StaticFileMiddleware支持不能识别的文件类型,并为它们设置一个默认的媒体类型,如下所示了具体采用的编程方式.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public
class
Program
{
public
static
void
Main()
{
new
WebHostBuilder()
.UseContentRoot(Directory.GetCurrentDirectory();)
.UseKestrel()
.Configure(app => app.UseStaticFiles(
new
StaticFileOptions {
ServeUnknownFileTypes =
true
,
DefaultContentType =
"image/jpg"
}))
.Build()
.Run();
}
}
|
上述这种解决方案只能设置一种默认媒体类型,如果具有多种需要映射成不同媒体类型的非识别文件类型,采用这种方案就无能为力了,所以最根本的解决方案还是需要将不能识别的文件类型和对应的媒体类型进行映射。由于StaticFileMiddleware使用的ContentTypeProvider是可以定制的,我们可以按照如下的方式显式地为StaticFileMiddleware指定一个FileExtensionContentTypeProvider对象作为它的ContentTypeProvider,然后将取缺失的映射添加到这个FileExtensionContentTypeProvider对象上.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public
class
Program
{
public
static
void
Main()
{
FileExtensionContentTypeProvider contentTypeProvider =
new
FileExtensionContentTypeProvider();
contentTypeProvider.Mappings.Add(
".img"
,
"image/jpg"
);
new
WebHostBuilder()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseKestrel()
.Configure(app => app.UseStaticFiles(
new
StaticFileOptions{
ContentTypeProvider = contentTypeProvider
}))
.Build()
.Run();
}
}
|
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,同时也希望多多支持我! 。
原文链接:http://www.cnblogs.com/artech/p/static-file-for-asp-net-core-01.html 。
最后此篇关于解析如何利用一个ASP.NET Core应用来发布静态文件的文章就讲到这里了,如果你想了解更多关于解析如何利用一个ASP.NET Core应用来发布静态文件的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
创建使用.NET框架的asp.net页面时,访问该页面的客户端是否需要在其计算机上安装.NET框架? IE。用户访问www.fakesite.com/default.aspx,如果他们没有安装框架,他
我阅读了很多不同的博客和 StackOverflow 问题,试图找到我的问题的答案,但最后我找不到任何东西,所以我想自己问这个问题。 我正在构建一个应用程序,其中有一个长时间运行的工作线程,它执行一些
已锁定。这个问题及其答案是locked因为这个问题是题外话,但却具有历史意义。目前不接受新的答案或互动。 我一直想知道为什么微软为这样一个伟大的平台选择了一个如此奇怪的、对搜索引擎不友好的名称。他们就
.Net Framework .Net .NET Standard的区别 1、.NET Framework 在未来.NET Framework或许成为过去时,目前还是有很多地方在使用的。这一套
如果有选择的话,您会走哪条路? ASP.NET Webforms + ASP.NET AJAX 或 ASP.NET MVC + JavaScript Framework of your Choice
我有一个 Web 服务,它通过专用连接通过 https 使用第三方 Web 服务,我应用了 ServicePointManager.ServerCertificateValidationCallbac
为什么我应该选择ASP.NET Web Application (.NET Framework)而不是ASP.NET Core Web Application (.NET Framework)? 我在
我在网络上没有找到任何关于包含 .NET Standard、.NET Core 和 .NET Framework 项目的 .NET 解决方案的公认命名约定。 就我而言,我们在 .NET 框架项目中有以
.NET Compact 是 .NET 的完美子集吗? 假设我考虑了屏幕大小和其他限制并避免了 .NET Compact 不支持的类和方法,或者 .NET Compact 是一个不同且不兼容的 GUI
我已经阅读了所有我能找到的关于 connectionManagement 中的 maxconnection 设置的文章:即 http://support.microsoft.com/kb/821268
我现在正在使用asp.net mvc,想知道使用内置的Json或 Json.Net哪个是更好的选择,但我不确定一个人是否比另一个人有优势。 另外,如果我确实选择沿用Json.Net的路线,那么我应该选
在 Visual Studio 中,您至少可以创建三种不同类型的类库: 类库(.NET Framework) 类库(.NET 标准) 类库(.NET Core) 虽然第一个是我们多年来一直使用的,但我
.NET 和 ASP.NET 之间有什么区别?它们有什么关系? 最佳答案 ASP.Net 基于 .Net 框架构建,提供有关 Web 开发的附加功能。 你可以去看看wikipedia article
在安装更高版本(3.0)之前,我需要安装.net框架1.1和2.0吗?或者单独安装 3.0 框架就足够了,并为在早期框架版本上编写的软件提供支持?谢谢 ,丽然 最佳答案 不,您不必安装以前的框架。 我
我正在开发一个项目,人们可以“更新”类别,例如更改类别的名称。我收到以下消息 This is called after clicking update 按钮 with the SQL statemen
.NET 类 System.Net.CookieContainer 线程安全吗? --更新:交 key 答复-- 是否有任何方法可以确保异步请求期间修改的变量(即 HttpWebRequest.Coo
我正在使用 JScript.NET 在我编写的 C# WinForms 应用程序中编写脚本。它工作得很好,但我只是尝试在脚本中放置一些异常处理,但我无法弄清楚如何判断我的 C# 代码抛出了哪种类型的异
我需要你的帮助, 比如我有一个小数类型的变量,我想这样取整。 例如 3.0 = 3 3.1 = 4 3.2 = 4 3.3 = 4 3.4 = 4 3.5 = 4 3.6 = 4 3.7 = 4 3.
我使用过这样的代码:http://msdn.microsoft.com/en-us/library/dw70f090.aspx在 ASP.NET 中工作之前访问数据库(2-3 年前)。我没有意识到我正
自 ConfigurationManager .NET Standard 中不存在,检索正在执行的程序集的应用程序设置的最佳方法是什么,无论是 web.config或 appSettings.{env
我是一名优秀的程序员,十分优秀!