手机版

分析如何使用ASP.NET核心应用程序发布静态文件

时间:2021-09-07 来源:互联网 编辑:宝哥软件园 浏览:

虽然ASP.NET Core是一个“动态”的Web服务器框架,但在很多情况下需要处理静态文件的请求,其中最常见的是JavaScript脚本文件、CSS样式文件和图片文件的请求。对于不同格式的静态文件请求的处理,ASP.NET核心为我们提供了三个中间件,这将是本系列文章的重点。然而,在介绍它们之前,我们将通过一些简单的例子来体验如何在ASP.NET核心应用程序中发布静态文件。

目录

首先,阅读网页形式的文件

其次,浏览目录的内容

第三,显示默认页面

第四,地图媒体类型

首先,阅读网页形式的文件

我们创建的演示示例是一个简单的ASP.NET核心控制台应用程序,项目结构如下图所示。我们可以看到,在默认为WebRoot的目录(wwwroot)下,我们将JavaScript文件、css样式文件和图片文件存储在相应的子目录(js、CSS和img)中,我们将以Web的形式发布这个目录下的所有文件,客户端可以访问相应的URL来获取这些文件。

对静态文件的请求是通过一个名为StaticFileMiddleware的中间件来实现的,该中间件在“微软。aspnetcore.staticfiles”,所以我们需要提前遵循这个NuGet包。整个应用程序只包含以下几行代码,通过调用ApplicationBuilder的扩展方法UseStaticFiles来完成UseStaticFiles的注册。

公共类Program { public static void Main(){ new WebHostBuilder()。UseContentRoot(目录。GetCurrentDirectory())。UseKestrel()。配置(app=app。UseStaticFiles())。构建()。run();}}除了注册必要的StaticFileMiddleware中间件,我们还调用了WebHostBuilder的UseContentRoot方法,将当前项目的根目录作为ContentRoot目录。我们知道ASP.NET核心应用程序有两个重要的根目录,即ContentRoot和WebRoot,这也是向外界发布的静态文件的默认根目录。由于WebRoot目录的默认路径是“{contentroot}/wwwroot”,所以上面的程序是将这个wwwroot目录中的所有静态文件发布到项目中。

程序运行后,我们可以通过向对应的URL发送一个HTTP请求来获取某个文件,这个URL是由相当于wwwroot目录的文件路径决定的。例如,JPG文件“~/wwwroot/img/dophin1.jpg”对应的URL为“http://”

localhost :5000/img/DOP hin 1 . jpg .我们直接用浏览器访问这个URL,目标图像就会直接显示出来。

上面,我们通过一个简单的例子直接发布了WebRoot所在目录下的所有静态文件。如果我们需要发布的静态文件存储在其他目录下呢?该应用程序仍在演示中。现在我们将一些文档存储在如下图所示的“~/doc/”目录中,并以Web的形式发布。我们应该如何编写程序?

我们知道,在大多数情况下,ASP.NET核心应用程序使用文件提供程序对象来读取文件,在处理静态文件的请求时也不例外。通过调用ApplicationBuilder的extension方法UseStaticFiles方法注册的UseStaticFiles类型的中间件在FileProvider和请求路径之间有映射关系。如果在没有指定任何参数的情况下调用UseStaticFiles方法,那么这个映射关系的请求路径就是应用程序的基址,而FileProvider自然就是指向WebRoot目录的PhysicalFileProvider。

上述需求可以通过显式注册这个映射来实现。为此,我们在现有程序的基础上增加了一个对UseStaticFiles方法的额外调用,并通过指定的参数(是StaticFileOptions对象)明确指定了采用的文件提供者(PhysicalFileProvider为“~/doc/”)和请求路径(“/documents”)。

公共类Program { public static void Main(){ string contentRoot=Directory }。GetCurrentDirectory();新的WebHostBuilder()。UseContentRoot(内容根)。UseKestrel()。配置(app=app。UseStaticFiles()。使用静态文件(新的静态文件选项{文件提供程序=新的物理文件提供程序(路径。Combine(contentRoot,' doc ')、RequestPath='/documents' })。构建()。run();}}根据上述程序中指定的映射关系,存储在目录“~/doc/”中的该pdf文件(“检查表. PDF”)在Web上发布的URL为“http://localhost 33605000/documents/checklist . PDF”。当我们在浏览器上请求这个地址时,PDF文件的内容会显示在浏览器上,如下图所示。

其次,浏览目录的内容

注册的静态文件中间件中间件将只处理特定静态文件的请求量。如果我们向某个目录的URL发送一个HTTP请求(如“http://localhost:5000/img//),我们将得到一个状态为404的响应。但是,我们可以注册另一个名为目录浏览器中间件的中间件来显示所请求目录的内容。具体来说,这个中间件将返回一个HTML页面,请求目录中的所有文件将以表格的形式包含在这个页面中。对于我们演示的应用程序,我们可以按如下方式调用UseDirectoryBrowser方法来注册目录浏览器中间件。

公共类Program { public static void Main(){ string contentRoot=Directory }。GetCurrentDirectory();IFileProvider文件提供程序=新的物理文件提供程序(路径。Combine(contentRoot,' doc ');新的WebHostBuilder()。UseContentRoot(内容根)。UseKestrel()。配置(app=app。UseStaticFiles()。使用静态文件(新的静态文件选项{文件提供程序=文件提供程序,请求路径='/文档' })。UseDirectoryBrowser()。UseDirectoryBrowser(新目录行选项{ FileProvider=fileProvider,RequestPath='/documents' })。构建()。run();}}上述应用启动后,如果我们使用浏览器对某个目录(如“http://localhost33605000/”或“http://localhost33605000/img/”)的URL进行寻址,目标目录(包括子目录和文件)的内容会显示在如下图所示的表格中。不仅如此,子目录和文件显示为链接,指向目标目录或文件的URL。

第三,显示默认页面

从安全的角度来看,使用注册的UseDirectoryBrowser中间件显示目录浏览页面,会暴露整个目标目录的所有接口和文件,所以这个中间件需要根据自身的安全策略谨慎使用。对于目录请求,另一种更常见的响应策略是显示保存在该目录中的默认页面。根据协议,作为默认页面的文件通常以以下四种方式命名:default.htm、default.html、index.htm或index.html。目标目录中默认页面的呈现是在一个名为DefaultFilesMiddleware的中间件中实现的。我们演示的应用程序可以调用UseDefaultFiles方法以下列方式注册这个中间件。

公共类程序{公共静态void Main(){字符串contentRoot=Directory } .GetCurrentDirectory();IFileProvider文件提供程序=新的物理文件提供程序(路径组合(contentRoot,' doc ');新的WebHostBuilder().UseContentRoot(内容根)。UseKestrel().配置(app=app .UseDefaultFiles().UseDefaultFiles(新的默认文件选项{请求路径='/documents ',文件提供程序=文件提供程序,}).UseStaticFiles().使用静态文件(新的静态文件选项{文件提供程序=文件提供程序,请求路径='/文档' })。UseDirectoryBrowser().UseDirectoryBrowser(新目录行选项{文件提供程序=文件提供程序,请求路径='/文档' }).构建()。run();} }现在我们在" ~/wwwroot/img/"目录下创建一个名为index.htm的默认页面,现在利用浏览器访问这个目录对应的网址(“http://localhost:5000/img/”,显示就时这个页面的内容。

我们必须在注册静态文件中间件和目录浏览器中间件之前注册默认文件中间件,否则它起不了任何作用。由于目录浏览器中间件和默认文件中间件这两个中间件处理的均是针对目录的请求,如果目录浏览器中间件先被注册,那么显示的总是目录的内容。若默认文件中间件先被注册,在默认页面不存在情况下回显示目录的内容。至于为什么要先于静态文件中间件之前注册默认文件中间件,则是因为后者是通过采用统一资源定位器重写的方式实现的,也就是说这个中间件会将针对目录的请求改写成针对默认页面的请求,而最终针对默认页面的请求还得依赖静态文件中间件完成。

默认文件中间件中间件在默认情况下总是以约定的名称(default.htm、default.html、index.htm或者index.html)在当前请求的目录下定位默认页面。如果我们希望作为默认页面的文件不能按照这样的约定命名(比如readme.htm),我们需要按照如下的方式显式指定默认页面的文件名。

公共类程序{公共静态void Main(){字符串contentRoot=Directory } .GetCurrentDirectory();IFileProvider文件提供程序=新的物理文件提供程序(路径组合(contentRoot,' doc ');DefaultFilesOptions选项1=new DefaultFilesOptions();DefaultFilesOptions options 2=new DefaultFilesOptions {请求路径='/documents ',文件提供程序=文件提供程序};选项1。默认文件名。添加('自述文件。htm’);选项2。默认文件名。添加('自述文件。htm’);新的WebHostBuilder().UseContentRoot(内容根)。UseKestrel().配置(app=app .UseDefaultFiles(选项1)。UseDefaultFiles(选项2)。UseStaticFiles().使用静态文件(新的静态文件选项{文件提供程序=文件提供程序,请求路径='/文档' })。UseDirectoryBrowser().UseDirectoryBrowser(新目录行选项{文件提供程序=文件提供程序,请求路径='/文档' }).构建()。run();} }四、映射媒体类型

通过上面演示的实例可以看出,浏览器能够正确的将请求的目标文件的内容正常的呈现出来。对超文本传送协议协议具有基本了解的人都应该知道,响应的文件能够在支持的浏览器上呈现具有一个基本的前提,那就是响应消息通过内容类型报头携带的媒体类型必须与内容一致。我们的实例演示了针对两种类型文件的请求,一种是使用联合图象专家组文件交换格式存储的编码图像文件扩展名文件,另一种是便携文档格式文件,对应的媒体类型分别是"图像/jpg "和"申请/pdf ",那么静态文件中间件是如何正确解析出正确的媒体类型的呢?

静态文件中间件对媒体类型的解析是通过一个名为ContentTypeProvider的对象实现的,默认情况下使用fileextensioncontenttyprovider对象。顾名思义,文件扩展内容类型提供程序根据文件的扩展命名来解析媒体类型。fileextensioncontenttyprovider在内部预先确定了数百种常见文件扩展名和相应媒体类型之间的映射关系,因此如果我们发布的静态文件具有标准扩展名,StaticFileMiddleware就可以为相应的响应分配正确的媒体类型。

因此,如果文件的扩展名不在这个预定义的映射中,或者如果我们需要一个预定义的扩展名来匹配不同的媒体类型,我们该怎么办?对于我们演示的这个示例,我想将文件“~/wwwroot/img/dophin1.jpg”的扩展名更改为。毫无疑问,staticfile中间件将能够为这个文件的请求解析正确的媒体类型。这个问题有几种不同的解决方法。第一个解决方案是让StaticFileMiddleware支持无法识别的文件类型,并为它们设置一个默认的媒体类型,如下所示。

公共类Program { public static void Main(){ new WebHostBuilder()。UseContentRoot(目录。GetCurrentDirectory();) .UseKestrel()。配置(app=app。使用静态文件(新的静态文件选项{ ServeUnknownFileTypes=true,DefaultContentType=' image/jpg ' })。构建()。run();}}上述解决方案只能设置一种默认媒体类型。如果有很多无法识别的文件类型需要映射到不同的媒体类型,那么这个解决方案是没有用的,所以最根本的解决方案就是映射无法识别的文件类型和对应的媒体类型。由于可以自定义staticfile中间件使用的ContentTypeProvider,我们可以通过以下方式为staticfile中间件显式指定一个fileextensioncontenttyprovider对象作为其ContentTypeProvider,然后将缺少的映射添加到这个fileextensioncontenttyprovider对象中。

公共类Program { public static void Main(){ file extensioncontenttype provider contenttype provider=new file extension contenttype provider();contentTypeProvider。映射。添加('。img ',' image/jpg ');新的WebHostBuilder()。UseContentRoot(目录。GetCurrentDirectory())。UseKestrel()。配置(app=app。使用静态文件(新的静态文件选项{ ContentTypeProvider=ContentTypeProvider })。构建()。run();}}以上就是本文的全部内容。希望本文的内容能给大家的学习或工作带来一些帮助。有问题可以留言交流,希望多多支持我们!

版权声明:分析如何使用ASP.NET核心应用程序发布静态文件是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。