手机版

ASP.NET核心MVC/WebAPI基础系列1

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

前言

最近好像发表了很多efcores,但是不要误以为我专门研究efcores。有时间私下一直在看ASP.NET芯的内容,所以后续会讲到efcores和ASP.NET芯。不要以为用了ASP.NET芯就很了解ASP.NET芯。虽然是基础系列,但也有你不知道的ASP.NET核心。

用户静态文件、用户默认文件、用户目录浏览器、用户文件服务器

当我们创建默认的。NET核心网络应用程序。NET Core默认将StaticFiles注入我们,这样我们就可以使用wwwroot目录中的StaticFiles。请注意,这里注入的静态文件是基于wwwroot目录中的静态文件。此时,我们通过使用UseDefaultFiles启用默认静态文件,如下所示。

app。UseDefaultFiles();app。UseStaticFiles();在此之前,我们在wwwroot目录中创建了四个静态HTML文件,如下所示:

根据官方的文档描述,我们创建了上面的四个静态html,同时我们按照上面的顺序在wwwroot目录中搜索静态html,找到了default.htm,那么对应的内容就显示如上,如果删除第一个html,就会找到default.html,以此类推。如果我们颠倒注射顺序呢?如下所示:

app。UseStaticFiles();app。UseDefaultFiles();

这时会出现404页,找不到页面。为什么呢?官方文档强调注入的默认文件一定要放在注入的静态文件之前,主要是因为注入的默认文件只是重写了URL,告诉路由我应该在wwwroot目录中寻找静态文件,但是实际上提供的是静态文件,这就是为什么注入的默认文件一定要放在注入的静态文件之前。但是如果我们必须在注入静态文件之前注入默认文件,我们该怎么办?接下来,使用文件服务器,它是UseDefaultFiles和UseStaticFiles的组合。因为它是一个组合,所以让我们先把UseFileServer放在前面。让我们试试这个问题,如下所示:

app。UseFileServer();app。UseStaticFiles();app。UseDefaultFiles();结果将显示默认的静态html,所以我不会在这里演示它。感兴趣的童鞋可以自己研究。接下来,让我们看一下启用目录浏览。启用目录浏览与在IIS上启用目录浏览相同,如下所示:

app。usedirentrybrowser();app。UseFileServer();app。UseStaticFiles();app。UseDefaultFiles();

这里就不需要多说了,那么问题来了:如果我们把使用MVC路由实现目录浏览放在后面呢?此时启用目录浏览会覆盖MVC路由吗?不,你可以自己验证。

app。UseMvc(routes={ routes。MapRoute(name: 'default ',template : ' { controller=Home }/{ action=Index }/{ id?}');});app。usedirentrybrowser();自定义默认文件目录

在修改默认文件名的基础上,公文有详细说明,这里就不演示了,浪费空间。接下来,我们将关注不同的。例如,默认情况下,静态文件是启用的,它位于wwwroot的根目录中。如果我们想把静态文件放在给定的第一张图片的dist文件夹中,会怎么样?这个时候我们该怎么办?那个。NET Core默认使用wwwroot目录作为静态文件目录,所以此时我们需要将其目录更改为wwwroot目录下的dist目录,并使用UseWebRoot方法将Web静态目录更改为wwwroot目录下的dist目录。当然,默认文件(UseDefaultFiles)是同时启用的,如下所示:UseWebRoot(路径。合并(目录。GetCurrentDirectory(),' wwwroot ',' dist ')

然后问题又来了。这时,假设我想把默认的静态文件放在外面,也就是项目的根目录。这个时候我们该怎么办?例如,访问以下静态html文件。

此时,我们可以使用UseDefaultFiles方法的重载将目录更改为项目根目录下的OutDefaultHtml目录,如下所示:

var fileProvider=新的物理文件提供程序(路径。合并(env。ContentRootPath,' OutefaultHTMl ');app。usedefault files(new default files options(){ file provider=file provider,default files=new[]{ ' outdefault . html ' } });因为我们更改了用于搜索静态html的目录,并最终为默认文件提供了UseStaticFiles,所以我们还需要通过重载UseStaticFiles方法来切换目录,使其不再wwwroot,如下所示:

app。UseStaticFiles(新的static file options(){ file provider=file provider });

除了组合使用UseDefaultFiles和UseStaticFiles,还有更简洁的方法吗?当然有。当默认的静态文件放在wwwroot目录下,已经不能满足我们的需求,我们需要自定义默认静态文件放置的目录时,我们建议使用两者的组合,即UseFileServer。我们可以对上述内容进行如下修改:

var fileProvider=新的物理文件提供程序(路径。合并(env。ContentRootPath,' OutefaultHTMl ');var file serverooptions=new file serverooptions();文件服务器选项。DefaultFileOptions . DefaultFilename=new[]{ ' OutDefault . html ' };文件服务器选项。FileProvider=fileProviderapp。UseFileServer(文件服务器选项);使用静态文件的详细说明

在大多数情况下,我们将静态文件放在wwwroot目录中,但在10%的情况下,静态文件将放在项目根目录中,因此默认注入的UseStaticFiles方法不再适用,我们需要使用其重载方法。例如,如果我们想访问下图中的mvc_course.gif,我们应该怎么做?

如上所述,有必要重载UseStaticFiles方法。第一个参数将目录切换到静态文件所在的目录,第二个参数是用于访问静态文件的虚拟路径。为了不暴露实际的物理路径,它如下:

app。使用静态文件(新的静态文件选项(){文件提供程序=新的物理文件提供程序(路径。合并(env。ContentRootPath,' outticfiles ')、request path='/outfiles ' });或者//app . usestaticfiles(new static fileopts()//{//file provider=new physicalfilepider(path.combine(env . contentrootpath,' outticfiles ')))),//request path=new path string('/outfiles ')/});

这个重载方法还有一个委托参数OnPrepareResponse,主要用来缓存静态文件。接下来,让我们专注于此。其实这篇文章才是重点。哈哈,直接上官网吧。

app。使用静态文件(新的静态文件选项(){文件提供程序=新的物理文件提供程序(路径。合并(env。ContentRootPath,' outticfiles ')、RequestPath='/outfiles ',onpreparereresponse=CTX={ const int cache control=60;ctx。上下文。响应。标头['缓存控制']='公共,最大年龄='缓存控制';} });公文如上设置,但实际上公文APi已经过时了。请求头的设置是通过header等枚举直接设置,而不是以字符串的形式设置,不容易出错,方便。请求头中缓存控制的上述设置可以通过以下两种方式完成。

向响应头添加缓存控制有什么实际效果?在这一点上,我们将讨论缓存控制的原理。上述缓存控制设置的到期时间为60秒。第一次被要求时,会回到200。在这个间隙,也就是60秒内重复刷新的话,永远是200。同时,它将从浏览器缓存中读取。一旦60秒过去,它将再次读取服务器上的图片。如果发现图片没有变化,则返回304,不做修改。那么问题来了,如果我们在这个间隙修改图片的内容,然后刷新图片的内容,会不会改变呢?答案是:不会,只要我们在缓存间隙时间内修改图片内容,刷新后仍然会显示原图片(除非强制ctrl F5刷新)。说到这里,让我们继续扩展并查看ASP.NET核心中的TagHelper特性:asp-append-version特性。这个特性和缓存控制的原理一样吗?接下来,我们来谈谈asp-append-version及其原理。

asp追加版本的详细说明和原理

让我们以wwwroot目录中的images文件下的图片为例,然后访问页面上的图片并添加asp-append-version,如下所示:

img src=' http : ~/images/MVC _ course . gif ' ASP-append-version=' true '/

此时响应返回的链接地址是:http://localhost 336063277/images/MVC _ course . gif?V=y3f-lvd 7x oqgqliwq _ wsufn 9 pops JIT 1 au 6 _ 0 IRR gwe从上图中还可以看到,此时图片的背面增加了一个版本号V,我们反复刷新后,版本号后面的字符串并没有变化。那么这个类似哈希码的值是怎么来的呢?根据请求网址和图片内容计算哈希码,即版本号。也就是说,只要我们改变图片的内容,当我们再次刷新或访问这个页面时,内容就会相应更新,这就是我们所说的缓存细分。与缓存控制相比,只要在缓存间隙时间内修改图片内容,图片仍会显示旧图片,除非强制刷新,而asp-append-version特性是你改、我改、你不改、我不改。就这么简单吗?接下来,让我们访问项目根目录中的图片,并通过UseStaticFiles重载访问外部图片,并添加asp-append-version功能。

img src=' http :/outfiles/MVC _ course . gif ' ASP-append-version=' true '/

哇,你看到什么了吗?你发现什么了吗?到目前为止,我们可以得出一个结论:asp-append-version特性只对WebRoot目录中的静态文件实现图像缓存,而外部静态文件是无效的。

那么,既然问题很突出,asp-append-version主要是针对WebRoot目录中的静态文件,而WebRoot只有wwwroot,那么我们可以说它只对wwwroot目录中的静态文件起作用,那么我们可以尝试把外部文件目录放在WebRoot目录中吗?以便缓存外部静态文件?让我们尝试在默认情况下将UseStaticFiles注入Startup.cs,并将其置于保留状态,这样默认情况下wwwroot下的样式、脚本和文件就不会发生任何变化。我们只是注入另一个UseStaticFiles,如下所示:

var compositeProvider=new compositeileprovider(env。WebRootFileProvider,新的物理文件提供程序(路径。合并(目录。GetCurrentDirectory(),' outrtticfiles ')));环境。WebRootFileProvider=compositeProvider;app。usestatifiles(new statifileoptions(){ file provider=compositeProvider,request path='/outfile ' });如上所述,默认的WebRoot,也就是wwwroot,保持不变,所以我们添加一个外部目录作为复合文件提供者作为WebRoot,一切保持不变。让我们如下参观。

img src=' http :/MVC _ course . gif ' ASP-append-version=' true '/如上所述,outticfiles的静态文件作为WebRoot目录访问,必须不添加outfiles的虚拟路径,这样就被视为外部静态文件,不会出现版本号。结果如下:

我们如何自定义向外部文件添加ASP-append-version number的效果?上面我们已经讲得很清楚了,asp-append-version的本质原理是根据请求URL和请求图片内容计算版本号,从而实现缓存。我们可以使用IMemoryCache接口进行缓存,可以通过请求上下文得到请求的路径,同时可以通过环境变量得到请求的静态文件所在的目录,所以只需要实现view extension方法。

视图扩展方法指向IRazorPage接口,然后参数就是我们的文件路径。我们很高兴ASP.NET核心有依赖注入,我们通过视图中的视图上下文获得请求上下文。然后获取注入的IMemoryCache和IHostingEnviroment接口。关于文件版本号,ASP.NET核心为我们提供了文件版本提供程序类,如下所示:

我们将参数传递给FileVersionProvider构造函数,最后将获得的文件版本号添加到我们请求的文件路径的尾部。代码如下:

公共静态类RazorPageExtension {公共静态字符串AddAppendVersion(此IRazorPage页面,字符串路径){ var context=page .ViewContext。HttpContextvar memoryCache=上下文RequestServices .GetService(类型为(IMemoryCache))作为IMemoryCache变量主机环境=上下文.RequestServices。GetService(类型为(IHostingEnvironment))作为IHostingEnvironmentvar文件版本提供程序=新文件版本提供程序(hostingenvironment .WebRootFileProvider,memoryCache,context .请求。路径);返回文件版本提供程序. AddFileVersionToPath(路径);} }

我们利用上述自定义实现的剃刀视图扩展方法来访问图片从而得到版本号试试,如下:

img src='http:@this .添加appendversion('/MVC _ course。gif ')'

总结

本文详细讲解了ASP .核心手动音量调节中静态文件以及缓存控制、ASP-追加版本本质原理,同时讲解了缓存控制和ASP-追加-版本区别所在。默认情况下ASP-追加版本只针对网站根目录有效,因为在访问根目录里面只存在wwwroot,要想对外部文件有效,可将外部文件所在目录也作为访问根目录来使用。

版权声明:ASP.NET核心MVC/WebAPI基础系列1是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。