当前位置: 首页 > news >正文

哪里查询网站备案seo技术培训岳阳

哪里查询网站备案,seo技术培训岳阳,搜索百度一下,驻马店网站建设公司前言静态文件#xff08;如 HTML、CSS、图像和 JavaScript#xff09;等是Web程序的重要组成部分。传统的ASP.NET项目一般都是部署在IIS上#xff0c;IIS是一个功能非常强大的服务器平台#xff0c;可以直接处理接收到的静态文件处理而不需要经过应用程序池处理#xff0c… 前言    静态文件如 HTML、CSS、图像和 JavaScript等是Web程序的重要组成部分。传统的ASP.NET项目一般都是部署在IIS上IIS是一个功能非常强大的服务器平台可以直接处理接收到的静态文件处理而不需要经过应用程序池处理所以很多情况下对于静态文件的处理程序本身是无感知的。ASP.NET Core则不同作为Server的Kestrel服务是宿主到程序上的由宿主运行程序启动Server然后可以监听请求所以通过程序我们直接可以处理静态文件相关。静态文件默认存储到项目的wwwroot目录中当然我们也可以自定义任意目录去处理静态文件。总之在ASP.NET Core我们可以处理静态文件相关的请求。StaticFile三剑客    通常我们在说道静态文件相关的时候会涉及到三个话题分别是启用静态文件、默认静态页面、静态文件目录浏览在ASP.NET Core分别是通过UseStaticFiles、UseDefaultFiles、UseDirectoryBrowser三个中间件去处理。只有配置了相关中间件才能去操作对应的处理相信大家对这种操作已经很熟了。静态文件操作相关的源码都位于GitHub aspnetcore仓库中的https://github.com/dotnet/aspnetcore/tree/v3.1.6/src/Middleware/StaticFiles/src目录。接下来我们分别探究这三个中间件的相关代码来揭开静态文件处理的神秘面纱。UseStaticFilesUseStaticFiles中间件使我们处理静态文件时最常使用的中间件因为只有开启了这个中间件我们才能使用静态文件比如在使用MVC开发的时候需要私用js css html等文件都需要用到它使用的方式也比较简单//使用默认路径即wwwroot app.UseStaticFiles(); //或自定义读取路径 var fileProvider new PhysicalFileProvider(${env.ContentRootPath}/staticfiles); app.UseStaticFiles(new StaticFileOptions {RequestPath/staticfiles,FileProvider fileProvider }); 我们直接找到中间件的注册类StaticFileExtensions[点击查看StaticFileExtensions源码]public static class StaticFileExtensions {public static IApplicationBuilder UseStaticFiles(this IApplicationBuilder app){return app.UseMiddlewareStaticFileMiddleware();}public static IApplicationBuilder UseStaticFiles(this IApplicationBuilder app, string requestPath){return app.UseStaticFiles(new StaticFileOptions{RequestPath new PathString(requestPath)});}public static IApplicationBuilder UseStaticFiles(this IApplicationBuilder app, StaticFileOptions options){return app.UseMiddlewareStaticFileMiddleware(Options.Create(options));} } 一般我们最常用到的是无参的方式和传递自定义StaticFileOptions的方式比较多StaticFileOptions是自定义使用静态文件时的配置信息类接下来我们大致看一下具体包含哪些配置项[点击查看StaticFileOptions源码]public class StaticFileOptions : SharedOptionsBase {public StaticFileOptions() : this(new SharedOptions()){}public StaticFileOptions(SharedOptions sharedOptions) : base(sharedOptions){OnPrepareResponse _ { };}/// summary/// 文件类型提供程序,也就是我们常用的文件名对应MimeType的对应关系/// /summarypublic IContentTypeProvider ContentTypeProvider { get; set; }/// summary/// 设置该路径下默认文件输出类型/// /summarypublic string DefaultContentType { get; set; }public bool ServeUnknownFileTypes { get; set; }/// summary/// 文件压缩方式/// /summarypublic HttpsCompressionMode HttpsCompression { get; set; } HttpsCompressionMode.Compress;/// summary/// 准备输出之前可以做一些自定义操作/// /summarypublic ActionStaticFileResponseContext OnPrepareResponse { get; set; } }public abstract class SharedOptionsBase {protected SharedOptionsBase(SharedOptions sharedOptions){SharedOptions sharedOptions;}protected SharedOptions SharedOptions { get; private set; }/// summary/// 请求路径/// /summarypublic PathString RequestPath{get { return SharedOptions.RequestPath; }set { SharedOptions.RequestPath value; }}/// summary/// 文件提供程序,在.NET Core中如果需要访问文件相关操作可使用FileProvider文件提供程序获取文件相关信息/// /summarypublic IFileProvider FileProvider{get { return SharedOptions.FileProvider; }set { SharedOptions.FileProvider value; }} } 我们自定义静态文件访问时最常用到的就是RequestPath和FileProvider,一个设置请求路径信息一个设置读取文件信息。如果需要自定义MimeType映射关系可通过ContentTypeProvider自定义设置映射关系var provider new FileExtensionContentTypeProvider(); provider.Mappings[.myapp] application/x-msdownload; provider.Mappings[.htm3] text/html; app.UseStaticFiles(new StaticFileOptions {ContentTypeProvider provider,//可以在输出之前设置输出相关OnPrepareResponse ctx {ctx.Context.Response.Headers.Append(Cache-Control, $public, max-age3600);} }); 接下来我们步入正题直接查看StaticFileMiddleware中间件的代码[点击查看StaticFileMiddleware源码]public class StaticFileMiddleware {private readonly StaticFileOptions _options;private readonly PathString _matchUrl;private readonly RequestDelegate _next;private readonly ILogger _logger;private readonly IFileProvider _fileProvider;private readonly IContentTypeProvider _contentTypeProvider;public StaticFileMiddleware(RequestDelegate next, IWebHostEnvironment hostingEnv, IOptionsStaticFileOptions options, ILoggerFactory loggerFactory){_next next;_options options.Value;//设置文件类型提供程序_contentTypeProvider options.Value.ContentTypeProvider ?? new FileExtensionContentTypeProvider();//文件提供程序_fileProvider _options.FileProvider ?? Helpers.ResolveFileProvider(hostingEnv);//匹配路径_matchUrl _options.RequestPath;_logger loggerFactory.CreateLoggerStaticFileMiddleware();}public Task Invoke(HttpContext context){//判断是够获取到终结点信息这也就是为什么我们使用UseStaticFiles要在UseRouting之前if (!ValidateNoEndpoint(context)){}//判断HttpMethod只能是Get和Head操作else if (!ValidateMethod(context)){}//判断请求路径是否存在else if (!ValidatePath(context, _matchUrl, out var subPath)){}//根据请求文件名称判断是否可以匹配到对应的MimeType如果匹配到则返回contentTypeelse if (!LookupContentType(_contentTypeProvider, _options, subPath, out var contentType)){}else{ //执行静态文件操作return TryServeStaticFile(context, contentType, subPath);}return _next(context);}private Task TryServeStaticFile(HttpContext context, string contentType, PathString subPath){var fileContext new StaticFileContext(context, _options, _logger, _fileProvider, contentType, subPath);//判断文件是否存在if (!fileContext.LookupFileInfo()){_logger.FileNotFound(fileContext.SubPath);}else{ //静态文件处理return fileContext.ServeStaticFile(context, _next);}return _next(context);} } 关于FileExtensionContentTypeProvider这里就不作讲解了主要是承载文件扩展名和MimeType的映射关系代码不复杂但是映射关系比较多有兴趣的可以自行查看FileExtensionContentTypeProvider源码,通过上面我们可以看到最终执行文件相关操作的是StaticFileContext类[点击查看StaticFileContext源码]internal struct StaticFileContext {private const int StreamCopyBufferSize 64 * 1024;private readonly HttpContext _context;private readonly StaticFileOptions _options;private readonly HttpRequest _request;private readonly HttpResponse _response;private readonly ILogger _logger;private readonly IFileProvider _fileProvider;private readonly string _method;private readonly string _contentType;private IFileInfo _fileInfo;private EntityTagHeaderValue _etag;private RequestHeaders _requestHeaders;private ResponseHeaders _responseHeaders;private RangeItemHeaderValue _range;private long _length;private readonly PathString _subPath;private DateTimeOffset _lastModified;private PreconditionState _ifMatchState;private PreconditionState _ifNoneMatchState;private PreconditionState _ifModifiedSinceState;private PreconditionState _ifUnmodifiedSinceState;private RequestType _requestType;public StaticFileContext(HttpContext context, StaticFileOptions options, ILogger logger, IFileProvider fileProvider, string contentType, PathString subPath){_context context;_options options;_request context.Request;_response context.Response;_logger logger;_fileProvider fileProvider;_method _request.Method;_contentType contentType;_fileInfo null;_etag null;_requestHeaders null;_responseHeaders null;_range null;_length 0;_subPath subPath;_lastModified new DateTimeOffset();_ifMatchState PreconditionState.Unspecified;_ifNoneMatchState PreconditionState.Unspecified;_ifModifiedSinceState PreconditionState.Unspecified;_ifUnmodifiedSinceState PreconditionState.Unspecified;//再次判断请求HttpMethodif (HttpMethods.IsGet(_method)){_requestType RequestType.IsGet;}else if (HttpMethods.IsHead(_method)){_requestType RequestType.IsHead;}else{_requestType RequestType.Unspecified;}}/// summary/// 判断文件是否存在/// /summarypublic bool LookupFileInfo(){//判断根据请求路径是否可以获取到文件信息_fileInfo _fileProvider.GetFileInfo(_subPath.Value);if (_fileInfo.Exists){//获取文件长度_length _fileInfo.Length;//最后修改日期DateTimeOffset last _fileInfo.LastModified;_lastModified new DateTimeOffset(last.Year, last.Month, last.Day, last.Hour, last.Minute, last.Second, last.Offset).ToUniversalTime();//ETag标识long etagHash _lastModified.ToFileTime() ^ _length;_etag new EntityTagHeaderValue(\ Convert.ToString(etagHash, 16) \);}return _fileInfo.Exists;}/// summary/// 处理文件输出/// /summarypublic async Task ServeStaticFile(HttpContext context, RequestDelegate next){//1.准备输出相关Header,主要是获取和输出静态文件输出缓存相关的内容//2.我们之前提到的OnPrepareResponse也是在这里执行的ComprehendRequestHeaders();//根据ComprehendRequestHeaders方法获取到的文件状态进行判断switch (GetPreconditionState()){case PreconditionState.Unspecified://处理文件输出case PreconditionState.ShouldProcess://判断是否是Head请求if (IsHeadMethod){await SendStatusAsync(Constants.Status200Ok);return;}try{//判断是否包含range请求即文件分段下载的情况if (IsRangeRequest){await SendRangeAsync();return;}//正常文件输出处理await SendAsync();_logger.FileServed(SubPath, PhysicalPath);return;}catch (FileNotFoundException){context.Response.Clear();}await next(context);return;case PreconditionState.NotModified:await SendStatusAsync(Constants.Status304NotModified);return;case PreconditionState.PreconditionFailed:await SendStatusAsync(Constants.Status412PreconditionFailed);return;default:var exception new NotImplementedException(GetPreconditionState().ToString());throw exception;}}/// summary/// 通用文件文件返回处理/// /summarypublic async Task SendAsync(){SetCompressionMode();ApplyResponseHeaders(Constants.Status200Ok);string physicalPath _fileInfo.PhysicalPath;var sendFile _context.Features.GetIHttpResponseBodyFeature();//判断是否设置过输出特征操作相关比如是否启动输出压缩或者自定义的输出处理比如输出加密等等if (sendFile ! null !string.IsNullOrEmpty(physicalPath)){await sendFile.SendFileAsync(physicalPath, 0, _length, CancellationToken.None);return;}try{//不存在任何特殊处理的操作作直接读取文件返回using (var readStream _fileInfo.CreateReadStream()){await StreamCopyOperation.CopyToAsync(readStream, _response.Body, _length, StreamCopyBufferSize, _context.RequestAborted);}}catch (OperationCanceledException ex){_context.Abort();}}/// summary/// 分段请求下载操作处理/// /summaryinternal async Task SendRangeAsync(){if (_range null){ResponseHeaders.ContentRange new ContentRangeHeaderValue(_length);ApplyResponseHeaders(Constants.Status416RangeNotSatisfiable);_logger.RangeNotSatisfiable(SubPath);return;}//计算range相关header数据ResponseHeaders.ContentRange ComputeContentRange(_range, out var start, out var length);_response.ContentLength length;//设置输出压缩相关headerSetCompressionMode();ApplyResponseHeaders(Constants.Status206PartialContent);string physicalPath _fileInfo.PhysicalPath;var sendFile _context.Features.GetIHttpResponseBodyFeature();//判断是否设置过输出特征操作相关比如是否启动输出压缩或者自定义的输出处理比如输出加密等等if (sendFile ! null !string.IsNullOrEmpty(physicalPath)){_logger.SendingFileRange(_response.Headers[HeaderNames.ContentRange], physicalPath);await sendFile.SendFileAsync(physicalPath, start, length, CancellationToken.None);return;}try{using (var readStream _fileInfo.CreateReadStream()){readStream.Seek(start, SeekOrigin.Begin); _logger.CopyingFileRange(_response.Headers[HeaderNames.ContentRange], SubPath);//设置文件输出起始位置和读取长度await StreamCopyOperation.CopyToAsync(readStream, _response.Body, length, _context.RequestAborted);}}catch (OperationCanceledException ex){_context.Abort();}} }由于代码较多删除了处主流程处理以外的其他代码从这里我们可以看出首先是针对输出缓存相关的读取设置和处理其此次是针对正常返回和分段返回的情况在返回之前判断是否有对输出做特殊处理的情况比如输出压缩或者自定义的其他输出操作的IHttpResponseBodyFeature分段返回和正常返回相比主要是多了一部分关于Http头Content-Range相关的设置,对于读取本身其实只是读取的起始位置和读取长度的差别。UseDirectoryBrowser目录浏览允许在指定目录中列出目录里的文件及子目录。出于安全方面考虑默认情况下是关闭的可以通过UseDirectoryBrowser中间件开启指定目录浏览功能。通常情况下我们会这样使用//启用默认目录浏览,即wwwroot app.UseDirectoryBrowser(); //或自定义指定目录浏览 var fileProvider new PhysicalFileProvider(${env.ContentRootPath}/MyImages); app.UseDirectoryBrowser(new DirectoryBrowserOptions {RequestPath /MyImages,FileProvider fileProvider }); 开启之后当我们访问https:///MyImages地址的时候将会展示如下效果通过一个表格展示目录里的文件信息等找到中间件注册类[点击查看DirectoryBrowserExtensions源码]public static class DirectoryBrowserExtensions {public static IApplicationBuilder UseDirectoryBrowser(this IApplicationBuilder app){return app.UseMiddlewareDirectoryBrowserMiddleware();}public static IApplicationBuilder UseDirectoryBrowser(this IApplicationBuilder app, string requestPath){return app.UseDirectoryBrowser(new DirectoryBrowserOptions{RequestPath new PathString(requestPath)});}public static IApplicationBuilder UseDirectoryBrowser(this IApplicationBuilder app, DirectoryBrowserOptions options){return app.UseMiddlewareDirectoryBrowserMiddleware(Options.Create(options));} } 这个中间件启用的重载方法和UseStaticFiles类似最终都是在传递DirectoryBrowserOptions接下来我们就看DirectoryBrowserOptions传递了哪些信息[点击查看DirectoryBrowserOptions源码]public class DirectoryBrowserOptions : SharedOptionsBase {public DirectoryBrowserOptions(): this(new SharedOptions()){}public DirectoryBrowserOptions(SharedOptions sharedOptions): base(sharedOptions){}/// summary/// 目录格式化提供默认是提供表格的形式展示,课自定义/// /summarypublic IDirectoryFormatter Formatter { get; set; } } 无独有偶这个类和StaticFileOptions一样也是集成自SharedOptionsBase类唯一多了IDirectoryFormatter操作通过它我们可以自定义展示到页面的输出形式接下来我们就重点看下DirectoryBrowserMiddleware中间件的实现public class DirectoryBrowserMiddleware {private readonly DirectoryBrowserOptions _options;private readonly PathString _matchUrl;private readonly RequestDelegate _next;private readonly IDirectoryFormatter _formatter;private readonly IFileProvider _fileProvider;public DirectoryBrowserMiddleware(RequestDelegate next, IWebHostEnvironment hostingEnv, IOptionsDirectoryBrowserOptions options): this(next, hostingEnv, HtmlEncoder.Default, options){}public DirectoryBrowserMiddleware(RequestDelegate next, IWebHostEnvironment hostingEnv, HtmlEncoder encoder, IOptionsDirectoryBrowserOptions options){_next next;_options options.Value;//默认是提供默认目录的访问程序_fileProvider _options.FileProvider ?? Helpers.ResolveFileProvider(hostingEnv);//默认传递的是HtmlDirectoryFormatter类型也就是我们看到的输出表格的页面_formatter options.Value.Formatter ?? new HtmlDirectoryFormatter(encoder);_matchUrl _options.RequestPath;}public Task Invoke(HttpContext context){//1.IsGetOrHeadMethod判断是否为Get或Head请求//2.TryMatchPath判断请求的路径和设置的路径是否可以匹配的上//3.TryGetDirectoryInfo判断根据匹配出来的路径能否查找到真实的物理路径if (context.GetEndpoint() null Helpers.IsGetOrHeadMethod(context.Request.Method) Helpers.TryMatchPath(context, _matchUrl, forDirectory: true, subpath: out var subpath) TryGetDirectoryInfo(subpath, out var contents)){//判断请求路径是否是/为结尾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;}//返回展示目录的内容return _formatter.GenerateContentAsync(context, contents);}return _next(context);}/// summary/// 根据请求路径匹配到物理路径信息是否存在存在则返回路径信息/// /summaryprivate bool TryGetDirectoryInfo(PathString subpath, out IDirectoryContents contents){contents _fileProvider.GetDirectoryContents(subpath.Value);return contents.Exists;} } 这个操作相对简单了许多主要就是判断请求路径能否和预设置的路径匹配的到如果匹配到则获取可以操作当前目录内容IDirectoryContents然后通过IDirectoryFormatter输出如何展示目录内容关于IDirectoryFormatter的默认实现类HtmlDirectoryFormatter这里就不展示里面的代码了逻辑非常的加单就是拼接成table的html代码然后输出有兴趣的同学可自行查看源码[点击查看HtmlDirectoryFormatter源码],如果自定义的话规则也非常简单主要看你想输出啥public class TreeDirectoryFormatter: IDirectoryFormatter {public Task GenerateContentAsync(HttpContext context, IEnumerableIFileInfo contents){//遍历contents实现你想展示的方式} } 然后在UseDirectoryBrowser的时候给Formatter赋值即可app.UseDirectoryBrowser(new DirectoryBrowserOptions {Formatter new TreeDirectoryFormatter() }); UseDefaultFiles很多时候出于安全考虑或者其他原因我们想在访问某个目录的时候返回一个默认的页面或展示这个事实我们就需要使用UseDefaultFiles中间件当我们配置了这个中间件如果命中了配置路径那么会直接返回默认的页面信息简单使用方式如下//wwwroot目录访问展示默认文件 app.UseDefaultFiles(); //或自定义目录默认展示文件 var fileProvider new PhysicalFileProvider(${env.ContentRootPath}/staticfiles); app.UseDefaultFiles(new DefaultFilesOptions {RequestPath /staticfiles,FileProvider fileProvider }); 老规矩我们查看下注册UseDefaultFiles的源码[点击查看DefaultFilesExtensions源码]public static class DefaultFilesExtensions {public static IApplicationBuilder UseDefaultFiles(this IApplicationBuilder app){return app.UseMiddlewareDefaultFilesMiddleware();}public static IApplicationBuilder UseDefaultFiles(this IApplicationBuilder app, string requestPath){return app.UseDefaultFiles(new DefaultFilesOptions{RequestPath new PathString(requestPath)});}public static IApplicationBuilder UseDefaultFiles(this IApplicationBuilder app, DefaultFilesOptions options){return app.UseMiddlewareDefaultFilesMiddleware(Options.Create(options));} } 使用方式和UseStaticFiles、UseDirectoryBrowser是一样,最终都是调用传递DefaultFilesOptions的方法我们查看一下DefaultFilesOptions的大致实现[点击查看源码]public class DefaultFilesOptions : SharedOptionsBase {public DefaultFilesOptions(): this(new SharedOptions()){}public DefaultFilesOptions(SharedOptions sharedOptions): base(sharedOptions){//系统提供的默认页面的名称DefaultFileNames new Liststring{default.htm,default.html,index.htm,index.html,};}/// summary/// 通过这个属性可以配置默认文件名称/// /summarypublic IListstring DefaultFileNames { get; set; } } 和之前的方法如出一辙都是继承自SharedOptionsBase通过DefaultFileNames我们可以配置默认文件的名称默认是default.html/htm和index.html/htm。我们直接查看中间件DefaultFilesMiddleware的源码[点击查看源码]public class DefaultFilesMiddleware {private readonly DefaultFilesOptions _options;private readonly PathString _matchUrl;private readonly RequestDelegate _next;private readonly IFileProvider _fileProvider;public DefaultFilesMiddleware(RequestDelegate next, IWebHostEnvironment hostingEnv, IOptionsDefaultFilesOptions options){_next next;_options options.Value;_fileProvider _options.FileProvider ?? Helpers.ResolveFileProvider(hostingEnv);_matchUrl _options.RequestPath;}public Task Invoke(HttpContext context){//1.我们使用UseDefaultFiles中间件的时候要置于UseRouting之上,否则就会不生效//2.IsGetOrHeadMethod判断请求为Get或Head的情况下才生效//3.TryMatchPath判断请求的路径和设置的路径是否可以匹配的上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);if (file.Exists){//判断请求路径是否已/结尾如果不是则从定向(这个点个人感觉可以改进)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;}//如果匹配的上则将配置的启用默认文件的路径遍历到的默认文件名称的路径组合成新的Path交给_next(context)//比如将组成类似这种路径/staticfiles/index.html向下传递context.Request.Path new PathString(context.Request.Path.Value defaultFile);break;}}}}return _next(context);} } 这个中间件的实现思路也非常简单主要的工作就是匹配配置的启用默认文件的路径遍历到的默认文件名称的路径是否存在如果匹配的上则将配置的启用默认文件的路径遍历到的默认文件名称的路径组合成新的Path(比如/staticfiles/index.html)交给后续的中间件去处理。这里值得注意的是UseDefaultFiles 必须要配合UseStaticFiles一起使用而且注册位置要出现在UseStaticFiles之上。这也是为什么UseDefaultFiles只需要匹配到默认文件所在的路径并重新赋值给context.Request.Path既可的原因。当然我们也可以自定义默认文件的名称因为只要能匹配的到具体的文件既可var defaultFilesOptions new DefaultFilesOptions {RequestPath /staticfiles,FileProvider fileProvider }; //我们可以清除掉系统默认的默认文件名称 defaultFilesOptions.DefaultFileNames.Clear(); defaultFilesOptions.DefaultFileNames.Add(mydefault.html); app.UseDefaultFiles(defaultFilesOptions); 总结    通过上面的介绍我们已经大致了解了静态文件处理的大致实现思路相对于传统的Asp.Net程序我们可以更方便的处理静态文件信息但是思路是一致的IIS会优先处理静态文件如果静态文件处理不了的情况才会交给程序去处理。ASP.NET Core也不例外通过我们查看中间件源码里的context.GetEndpoint()null判断可以知道ASP.NET Core更希望我们优先去处理静态文件而不是任意出现在其他位置去处理。关于ASP.NET Core处理静态文件的讲解就到这里欢迎评论区探讨交流。????欢迎扫码关注我的公众号????
http://www.yutouwan.com/news/403664/

相关文章:

  • 如何在网站上做自动弹出潍坊哪里有做360网站的
  • 怎么给网站创建二维码拼多多关键词排名查询工具
  • 专业 网站设计公司价格惠州网络推广公司哪家好
  • 网站开发实战asp制作视频成都移动网站建设
  • 最低的成本做网站可视化网页编辑工具
  • 企业网站seo案例分析建设厅的证全国通用吗
  • 大型门户网站开发方案新建设电影院 网站
  • 网站服务器地址查询合肥关键词排名
  • 哪个网站上做ppt比较好看的图片网站建设评估
  • wordpress有哪些网站有没有网站免费的
  • 济南网站建设公司大全wordpress 浏览ppt
  • 中企动力做网站价格注册建设网站的公司
  • 深圳网站设计我选刻企业计划书怎么写
  • 佛山市网站建设公司什么是营销型手机网站建设
  • 网站建设的原理天津塘沽爆炸地点
  • 自己做书画交易网站找网站建设需要问什么软件
  • 排版设计模板网站网站建设第二年费用
  • 网站搭建好后被移动宽带屏蔽怎么办莱州市双语网站
  • 网站建设新闻咨询wordpress 收费版
  • 网站 快照 更新慢软件开发培训哪里好
  • 二维码怎么做网站江苏公司网站建设
  • 目前网站开发怎么兼顾手机广告片
  • 投资担保网站建设将网页制作成app
  • 西安做网站公司xamokjwordpress vtrois
  • 个人网站备案能做什么内容科技与狠活是什么梗
  • 中国建设职业注册中心网站免费网站平台推荐
  • 上海网站建设网页制作怎么样周口网站建设 网站制作 网络推广
  • 南宁网站制作开发公司泰安千橙网站建设优化熊掌号
  • 做便宜网站珠海网站建设制作
  • 查询网站流量的网址微网站域名