下载正品官方网站,简述网站制作步骤,河北建设厅网站查询,在视频网站中做节目怎么挣钱前言如今前后端分离开发模式如火如荼#xff0c;开发职责更加分明#xff08;当然前后端一起搞的模式也没有完全褪去#xff09;#xff1b;而对于每个公司产品实施来说#xff0c;部署模式会稍有差别#xff0c;有的会单独将前端文件部署为一个站点#xff0c;有的会将… 前言如今前后端分离开发模式如火如荼开发职责更加分明当然前后端一起搞的模式也没有完全褪去而对于每个公司产品实施来说部署模式会稍有差别有的会单独将前端文件部署为一个站点有的会将前端文件和后端站点整合一起部署通常当项目规模比较大的时候分开站点部署是不错的选择管理和维护清晰而对于一些小型项目整合在一起部署为一个站点就显得相对比较方便毕竟有时候开发是你、部署是你、维护也是你如果选择整合部署或者是项目包含静态文件(如图片)的访问接下来的内容就有用武之地了~~~正文Asp.NetCore的请求管道是根据需求通过注册中间件进行构造的(构造过程参考跟我一起学.NetCore之中间件(Middleware)简介和解析请求管道构建)而通过模板创建出来的项目请求管道中默认只有关键的几个中间件如果有其他需要可以自己添加注册。其中静态文件中间件默认就没有如下案例如上例运行结果是访问不到添加的index.html可能有小伙伴会说那是因为没有加目录然而并不是这个原因 现在注册上静态文件中间件试试为什么要创建wwwroot目录呢其他目录不行吗当注册静态文件中间件时通过构造函数可以看出(看下面静态文件中间件的构造函数截图)可以指定对应的静态文件目录当没有指定目录时默认就会使用IHostingEnvironment中的WebRootFileProvider而WebRootFileProvider默认就指定了wwwroot在IHostingEnvironment的扩展方法Initialize中指定这里就不一一去扒代码了如果有兴趣的小伙伴可以按照以下思路去扒那如何指定目录在扒代码的过程中应该会看到注册中间件的时候可以传参进行指定如下根据需求可以注册多个静态文件中间件如上所示请求到请求管道时会先到wwwroot目录中去找匹配文件如果找不到继续下一个中间件去指定的myFile目录中去匹配文件。往往在开发过程中会对相关静态文件进行分类同时Url地址也要不同通常会通过注册中间件时将对应静态文件目录映射到指定Url目录如下搞过IIS的小伙伴应该都知道设置默认文件的配置吧通过现成的中间件也能实现如下注册中间件实现能减少配置当然也是不错的选择到这小伙伴们应该尝试一下将wwwroot目录下的index.html的名字改改再运行一下同样的访问Url地址肯定访问不了的如果能那估计是存在缓存可以清清缓存再试 那为什么呢定位很精确肯定是默认文件这个中间件再搞事情来看看里面咋实现的// 定义默认文件中间件
public class DefaultFilesMiddleware
{// 选项配置private readonly DefaultFilesOptions _options;private readonly PathString _matchUrl;private readonly RequestDelegate _next;// 静态文件目录读取Provider默认目录是wwwrootprivate readonly IFileProvider _fileProvider;// 构造函数用于初始化对应的变量public DefaultFilesMiddleware(RequestDelegate next, IWebHostEnvironment hostingEnv, IOptionsDefaultFilesOptions options){// 校验参数if (next null){throw new ArgumentNullException(nameof(next));}if (hostingEnv null){throw new ArgumentNullException(nameof(hostingEnv));}if (options null){throw new ArgumentNullException(nameof(options));}_next next;// 初始化配置信息_options options.Value;// 如果没有指定对应的IFileProvider就用IWebHostEnvironment的WebRootFileProvider默认目录就wwwroot_fileProvider _options.FileProvider ?? Helpers.ResolveFileProvider(hostingEnv);_matchUrl _options.RequestPath;}// 默认文件中间件的关键方法public Task Invoke(HttpContext context){if (context.GetEndpoint() null Helpers.IsGetOrHeadMethod(context.Request.Method) Helpers.TryMatchPath(context, _matchUrl, forDirectory: true, subpath: out var subpath)){var dirContents _fileProvider.GetDirectoryContents(subpath.Value);if (dirContents.Exists){// 依次遍历默认文件检查对应文件是否在指定目录中存在这里是关键for (int matchIndex 0; matchIndex _options.DefaultFileNames.Count; matchIndex){string defaultFile _options.DefaultFileNames[matchIndex];var file _fileProvider.GetFileInfo(subpath.Value defaultFile);// TryMatchPath will make sure subpath always ends with a / by adding it if needed.if (file.Exists){// 如果路径与目录匹配但没有以斜杠结尾则重定向以添加斜杠.// This prevents relative links from breaking.if (!Helpers.PathEndsInSlash(context.Request.Path)){context.Response.StatusCode StatusCodes.Status301MovedPermanently;var request context.Request;var redirect UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path /, request.QueryString);context.Response.Headers[HeaderNames.Location] redirect;return Task.CompletedTask;}// 如果匹配找到就重写请求地址由下一个中间件处理所以在个中间件的注册一定要在UseStaticFiles前面否则会报错context.Request.Path new PathString(context.Request.Path.Value defaultFile);break;}}}}// 执行下一个中间件return _next(context);}
}
在中间件Invoke方法中遍历_options.DefaultFileNames进行匹配但我们并没有指定猜想应该是有默认设置去看看对应的DefaultFilesOptionspublic DefaultFilesOptions(SharedOptions sharedOptions): base(sharedOptions)
{// 果然在构造函数中指定了默认列表DefaultFileNames new Liststring{default.htm,default.html,index.htm,index.html,};
}
果然在DefaultFilesOptions的构造函数有对应的默认列表现在是不是豁然开朗了~~~那如果一定要指定其他文件怎么办呢老规矩注册中间件时传参是不是很简单再来个需求比如想做一个在线文件管理系统那肯定得访问目录吧现在肯定不能访问的小伙伴们可以试试 通过注册中间又可以实现是不是觉得中间件很是灵活而且还很强大这里对于参数的设置就不一一举例了用法和UseStaticFiles参数差不多一致小伙伴感兴趣可私下试试。其实微软早就想到一会要这么干一会要那么干了所以直接提供了一个全功能的中间件直接UseFileServer即可可以针对上面说到的每一项进行配置如下其实内部就是整合以上说到的中间件如下源码详细配置这里就不一一配置测试了使用和单独注册中间件时一致这里只是整合在一起而已。总结说好的偏应用还是没忍住扒代码但是感觉适当的扒扒能说的更清楚一些下一节说说路由的最佳实践。