ASP.NET Core 文件系统

紧接上一讲 中间件 之后,今天来我们来讲一下关于 ASP.NET  Core 中静态文件服务。


什么是静态文件?

先看一下下面例子(在客户端浏览器中通过 url 路径访问了网站的一张图片):

640?wx_fmt=png

这样的图片就是一个静态文件

640?wx_fmt=png

  • 静态文件(staticfiles),其实就是指像 HTMLCSS图片 和 JavaScript 之类固定的文件,是会被应用程序直接提供给客户端的资源。

  • 静态文件通常位于web root(内容根目录或Web根目录)文件夹下。有关 内容根目录 和 Web根目录 的信息在第一讲中介绍过。

    640?wx_fmt=png

    •  Web根目录默认为的是 Contentroot 路径下的 wwwroot 文件夹。

    •  静态文件中间件将默认只读取 Web根目录和其子目录中的文件。

    •  对于 Razor (.cshtml) 文件,波浪号斜杠 ~/ 指向 webroot。 以 ~/ 开头的路径称为虚拟路径。

    • 内容根目录(Contentroot):是应用程序所用到的所有内容的根路径。WebHost.CreateDefaultBuilder() 中默认下把项目的当前目录设置为内容根目录,也就是指 web 的项目的文件夹,包括 bin 和 webroot 文件夹。

    • Web根目录(webroot):项目中用于存放类似于 CSS、JS、图片等公开、静态资源的目录。

  • 静态文件可以保存在 Web根目录(默认为wwwroot) 下的任意文件夹内,并通过相对根的路径来访问。例如当你通过 VisualStudio 创建一个默认的 Web应用程序(MVC)项目时,在 wwwroot 目录下会多出几个文件夹:css、images以及js。

    640?wx_fmt=png

    通过下面的URL就能够直接访问 images 目录下的图片:
    http://<app>/images/<imageFileName>
    http://localhost:7819/images/banner1.svg

    640?wx_fmt=png


静态文件中间件

如上例子,为了能够使用静态文件的服务,必须配置中间件,把静态文件中间件加入到请求管道内。(默认创建的 MVC Web应用程序已经配置了)
静态文件中间件可通过下述方法来配置:在项目中增加 MicrosoftAspNetCore.StaticFiles 包依赖,然后从Startup.Configure 中调用 app.UseStaticFiles 扩展方法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env){
app.UseStaticFiles();

上面我们通过一个简单的实例使用 app.UseStaticFiles() 来使用文件中间件,使得Web根目录下的所有静态文件直接发布出来。如果我们需要发布的静态文件存储在其他目录下呢?依旧是这个应用,现在我们将静态文件放在自定义文件夹 MyStaticFiles 内,并将以Web的形式发布出来,展示如何通过使用 UseStaticFiles将其他非wwwroot目录下的内容也向外提供服务。

<mxfile userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36" version="8.5.3" editor="www.draw.io" type="device"><diagram>7Vtdk5owFP01PnaHEEB9rPbroZ3pdDvT5ygR00ZCQyxuf31vIBHZ6K6tQN1ddpydcMNHcs89h9wbHeH5Zvdekmz9ScSUj3wv3o3wm5HvY8+D/9pwVxkCNK4MiWRxZfJqwy37TSsjstYti2neOFEJwRXLjBFVxqVIU7pUjROJlKJoXrsSPG5cl5GEOobbJeGu9RuL1bqyTvxxbf9AWbI2T0YomlY9C7L8kUixTc3zRj5elX9V94bYe5mR5WsSi+LAhN+O8FwKoarWZjenXLu26bZ3J3r345Y0Vedc4FcX/CJ8S+2Iy3GpO+sLGGKmm3BTxQj/Av4maaJ7Z0pk0OFBi9OVMk1p/KLbC6GU2JgDwlmSQrs6d/aLwv3A5a+NubzZbMU4nwsuJFhSkeqn5BlZsjT5WD0i8mrTF/OoAEwC7rfipS/XLI5pqociFFFkUc5EX5YJlqoyNMIZfMA1c+8mHIUwzTkco/oYPvp0qeYizZUkrHQnJbkqaK5HH0uRfSUyoXaqK5EqE8gIYJy5SBhw9Lzp7sBkkHlPxYYqeQenmN7QBIkl0WRSHRd1SCIbSOuDcPQjwwTDgmR/5zoSoGGC4Xhg4IsCo3SGOROdCpRGcBzB/ax4aQZH0FZsPAa/nrOZ2+PA+yeA3+uXGUZDAxoBcYB4GHUDePA44JxVfFRS/NjrIvon8DYAAz8g99cyQF4hB1HsIoqPoMfJgvLPImeKCX1/I0J/iWoHHEZe1CRxhBwSW98fQjq5HNFw0PYno+0hwv1pezRoe2vaHp4A/qq0fTwowZNRAjzpUQkmgxK0pgTjE8BflRJMByV4MkoQeNP+lMBWXgYpaEEKpieQvyopQMhBvCiKsvTkR1zPeSGhlaj9FA9CAeal7Wu14cYrVVZ4D9EHQF6Ct6h8KDUs1kzRWwBXP7OQJCtB3KYxjQ2ELXAO4Xv5WRg6pAuOcc5rAQE354bwUzCZl4aCrWzZNVDk9QfCGWnyUPhoofBxZF3bUeEDuQnup7tb8BtbvmOc5s+XRyiYNp0+HvdHpDOSiYFIf4+p743vESnojUhuuqBgnjdZmjxfDvk4/G8c8s9YhQ8cuvxlhKd+Xxzy3WX2gqXPlz7Ihuy+ntXfgto+eqBPx2s5u8LqgT7uRrRYfH859Ak8d9O/M/q4qdBnKTLtj+e9aEZNl2N3i7Yzl1+2FzcUZHstyGL3VdZZQfbCTbuhINv4Bk50AvqrqsheuB03iEGvYnCkRtmdGFy2bzeIQUMMJiegvyoxwG7e6EA+5DIt5DLYXWB3lMvgY+mp2eRpABv93Ao7/Vd5Of/XcAIKsl3daXeFbtyNoodMMMhFvaH0craYEGqWxkOLRg+rfHzGt6kHLl/O5dDrrS6B3b1bBgG7uymZcs0sOvLac0B4IFe+twqaut9RaYlFcFj/DqbsO/itEX77Bw==</diagram></mxfile>

如果要访问 MyStaticFiles 文件夹下的 test.png 图片,可以这样配置静态文件中间件:

public void Configure(IApplicationBuilder app, IHostingEnvironment env){
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
RequestPath = new PathString("/StaticFiles"),
});
}

ASP.NET Core 一般情况下都是利用一个FileProvider 对象来读取文件的,它在处理针对静态文件的请求是也不例外。

上边代码在静态文件中间件中,在调用静态文件中间件的方法 UseStaticFiles(),该方法可接受一个配置项对象 StaticFileOptions,其内部具有一个 FileProvider 和请求路径的映射关系。

如果调用 UseStaticFiles方法没有指定任何的参数,那么这个映射关系的请求路径就是应用的基地址(PathBase),而FileProvider自然就是指向WebRoot目录的PhysicalFileProvider。

通过访问 http://<app>/StaticFiles/test.png,这样就能访问到 test.png 图片文件了。

640?wx_fmt=png

静态文件授权 :

静态文件中间件默认不提供授权检查。任何通过该模块提供访问的文件,包括位丁 wwwroot 下的文件都是公开的,那么如何给文件提供授权呢?

将文件保存在 wwwroot 之外,并将目录设置为可被静态文件中间件访问到,同时通过一个 controller action 来访问,通过授权后返回HleResulU将文件保存在wwwroot之外,并将目录设置为可被静态文件中间件访问到,同时通过一个itrolleraction来访问,通过授权后返回 FileResult。


目录浏览

以上通过注册的 StaticFileMiddleware 只会处理针对某个具体静态文件的请求,如果我们向某个目录的URL发送HTTP请求,得到的将是一个状态为404的响应。那是因为基于安全考虑,默认情况下应用程序是禁用目录访问功能的。目录浏览就是允许网站用户看到指定目录下的目录和文件列表。我们可以通过注册一个名为DirectoryBrowserMiddleware 的中间件来显示请求目录的内容:

Step1. 在Startup.ConfigureServices 中调用 AddDirectoryBrowser 扩展方法添加目录浏览服务:

public void ConfigureServices(IServiceCollection services){
services.AddDirectoryBrowser();
}

Step2. 然后在 Startup.Configure 中调用 UseDirectoryBrowser 扩展方法使用中间件来开启网络应用目录浏览:

public void Configure(IApplicationBuilder app, IHostingEnvironment env){
app.UseStaticFiles();

app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
RequestPath = new PathString("/StaticFiles"),
});

app.UseDirectoryBrowser(new DirectoryBrowserOptions()
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
RequestPath = new PathString("/StaticFiles"),
});
}

运行程序后,就可以通过访问 http:<app>/StaticFiles 来浏览 ContentRoot/StaticFiles 文件夹中的目录了。这个中间件会返回一个HTML页面,将请求目录下的所有文件将以表格的形式包含在这个页面中(包括该文件夹下的每一个文件夹与文件)

640?wx_fmt=png

注意:使用静态文件目录浏览的区别,上述Step2.Startup.Configure方法中调用了两个 app.UseStaticFiles:第一个调用允许请求 wwwroot 文件夹下的静态文件,第二个调用则是允许通过 http:<app>/StaticFiles/<fileName> 请求 StaticFiles 文件夹中的静态文件,调用 app.UseDirectoryBrowser 则是允许通过 http:<app>/StaticFiles 请求浏览 StaticFiles 文件夹的目录。

注册指定目录的浏览

   app.UseDirectoryBrowser 方法可接受一个配置项对象 DirectoryBrowserOptions,该对象与静态文件中间件配置项对象相似,通过该对象可以配置允许用户浏览的目录和请求的虚拟路径。

 


默认文件

设置默认首页能给站点的每个访问者提供一个默认起始页。为了使站点能够提供默认页面,避免用户输入完整URL,我们可以在 Startup.Configure 中调用 app.UseDefaultFiles 扩展方法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory){
app.UseDefaultFiles();
app.UseStaticFiles();
}

app.UseDefaultFiles 必须是在 UseStaticFiles 之前调用。UseDefaultFiles只是重写了URL,而不是真的提供了这样一个文件。因此必须开启静态文件中间件(UseStaticFiles)来提供这个文件。
通过 UseDefanltFiles,请求文件夹的时候将检索以下文件:

  • default.htm

  • default.html

  • index.htm

  • index.html

列表中第一个被找到的文件将返回给用户,作为该完整URL的请求的应答,而此时浏览器上URL将继续显示用户输入的URI。

指定默认文件

静态文件中间件可以接受一个 DefaultFilesOptions 的配置对象参数,通过添加默认主页名称,可以指定自定义的默认文件(默认首页),下面的代码展示如何将默认文件名改为 myindex.html

public void Configure(IApplicationBuilder app)
{
DefaultFilesOptions options = new DefaultFilesOptions();
options.DefaultFileNames.Clear(); // 清除默认文件
options.DefaultFileNames.Add("login.html"); //添加指定文件为默认文件
app.UseDefaultFiles(options); //使用默认文件中间件
app.UseStaticFiles();     //使用静态文件中间件(必须)
}

在 web根目录中添加好 login.html 页面,运行程序:


UseFileServer

UseFileServer 集合了 UseStaticFilesUseDefaultFiles以及UseDirectoryBrowser
下面的代码启用了静态文件和默认文件,但不允许直接访问目录:

下面的代码启用了静态文件、默认文件和目录浏览功能:

app.UseFileServer(enableDirectoryBrowsing:true);

作为一个集合了UseStaticFilesUseDefaultFilesUseDirectoryBrowser方法于一体的方法,如果希望提供 web根目录之外存在的文件,则需要实例化并配置一个 FileServerOptions 对象传递给app.UscFileServer 的参数。例如,在应用中有如下层次的目录:

<mxfile userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36" version="8.5.3" editor="www.draw.io" type="device"><diagram>7Vtdk5owFP01PnaHEEB9rPbroZ3pdDvT5ygR00ZCQyxuf31vIBHZ6K6tQN1ddpydcMNHcs89h9wbHeH5Zvdekmz9ScSUj3wv3o3wm5HvY8+D/9pwVxkCNK4MiWRxZfJqwy37TSsjstYti2neOFEJwRXLjBFVxqVIU7pUjROJlKJoXrsSPG5cl5GEOobbJeGu9RuL1bqyTvxxbf9AWbI2T0YomlY9C7L8kUixTc3zRj5elX9V94bYe5mR5WsSi+LAhN+O8FwKoarWZjenXLu26bZ3J3r345Y0Vedc4FcX/CJ8S+2Iy3GpO+sLGGKmm3BTxQj/Av4maaJ7Z0pk0OFBi9OVMk1p/KLbC6GU2JgDwlmSQrs6d/aLwv3A5a+NubzZbMU4nwsuJFhSkeqn5BlZsjT5WD0i8mrTF/OoAEwC7rfipS/XLI5pqociFFFkUc5EX5YJlqoyNMIZfMA1c+8mHIUwzTkco/oYPvp0qeYizZUkrHQnJbkqaK5HH0uRfSUyoXaqK5EqE8gIYJy5SBhw9Lzp7sBkkHlPxYYqeQenmN7QBIkl0WRSHRd1SCIbSOuDcPQjwwTDgmR/5zoSoGGC4Xhg4IsCo3SGOROdCpRGcBzB/ax4aQZH0FZsPAa/nrOZ2+PA+yeA3+uXGUZDAxoBcYB4GHUDePA44JxVfFRS/NjrIvon8DYAAz8g99cyQF4hB1HsIoqPoMfJgvLPImeKCX1/I0J/iWoHHEZe1CRxhBwSW98fQjq5HNFw0PYno+0hwv1pezRoe2vaHp4A/qq0fTwowZNRAjzpUQkmgxK0pgTjE8BflRJMByV4MkoQeNP+lMBWXgYpaEEKpieQvyopQMhBvCiKsvTkR1zPeSGhlaj9FA9CAeal7Wu14cYrVVZ4D9EHQF6Ct6h8KDUs1kzRWwBXP7OQJCtB3KYxjQ2ELXAO4Xv5WRg6pAuOcc5rAQE354bwUzCZl4aCrWzZNVDk9QfCGWnyUPhoofBxZF3bUeEDuQnup7tb8BtbvmOc5s+XRyiYNp0+HvdHpDOSiYFIf4+p743vESnojUhuuqBgnjdZmjxfDvk4/G8c8s9YhQ8cuvxlhKd+Xxzy3WX2gqXPlz7Ihuy+ntXfgto+eqBPx2s5u8LqgT7uRrRYfH859Ak8d9O/M/q4qdBnKTLtj+e9aEZNl2N3i7Yzl1+2FzcUZHstyGL3VdZZQfbCTbuhINv4Bk50AvqrqsheuB03iEGvYnCkRtmdGFy2bzeIQUMMJiegvyoxwG7e6EA+5DIt5DLYXWB3lMvgY+mp2eRpABv93Ao7/Vd5Of/XcAIKsl3daXeFbtyNoodMMMhFvaH0craYEGqWxkOLRg+rfHzGt6kHLl/O5dDrrS6B3b1bBgG7uymZcs0sOvLac0B4IFe+twqaut9RaYlFcFj/DqbsO/itEX77Bw==</diagram></mxfile>

对于上面这个层次结构的示例,你可能需耍启用静态文件、默认文件以及浏览 MyStaticFiles 目录等功能。下面的代码片段演示了如何通过调用一次 FileServerOptions 来完整实现这些功能:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory){
app.UseFileServer(new FileServerOptions()
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
RequestPath = new PathString("/StaticFiles"),
EnableDirectoryBrowsing = true,
EnableDefaultFiles = true,
});
}

如果将 enableDirectoryBrowsing设置为true,则必须要在 Startup.ConfigureServices 中调用 services.AddDirectoryBrowser 扩展方法:

public void ConfigureServices(IServiceCollection services){
services.AddDirectoryBrowser();
}

如果在 MyStaticFiles 目录下存在默认页面,则打开默认页面。如果没有默认命名的文件,则http://StaticFiles将返回目录 StaticFiles 的目录列表,如下图所示。

640?wx_fmt=png

StaticFiles中存在默认页面

640?wx_fmt=png

StaticFiles中不存在默认页面


FileExtensionContentTypeProvider

FileExtensionContentTypeProvider 类内包含一个将文件扩展名映射到 MIME内容类型的集合。在下面的例子中,将多个文件扩展名(如:.myapp)注册为已知的MIME类型(application/x-msdownload),“.rtf”被替换,“.mp4”被移除:

public void Configure(IApplicationBuilder app){
FileExtensionContentTypeProvider provider = new FileExtensionContentTypeProvider();

provider.Mappings[".myapp"] = "application/x-msdownload";
provider.Mappings[".htm3"] = "text/html";
provider.Mappings[".image"] = "image/png";


provider.Mappings[".rtf"] = "application/x-msdownload";


provider.Mappings.Remove(".mp4");
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
RequestPath = new PathString("/StaticFiles"),
ContentTypeProvider = provider,
});

app.UseDirectoryBrowser(new DirectoryBrowserOptions()
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
RequestPath = new PathString("/StaticFiles"),
});
}

非标准的内容类型

ASP.NET Core 静态文件中间件能够支持超过400多种己知的文件内容类型。如果用户请求一个未知的文件类型,静态文件中间件将返 HTTP404(未找到)响应。如果启用目录浏览,则该文件的URL将会被显示,但访问URL会返回一个 HTTP404 错误。下面则通过代码把不能识别的类型和文件作为下载的文件处理:

public void Configure(IApplicationBuilder app){
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
RequestPath = new PathString("/StaticFiles"),
ServeUnknownFileTypes = true,
DefaultContentType = "application/x-msdownload",
});

app.UseDirectoryBrowser(new DirectoryBrowserOptions()
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
RequestPath = new PathString("/StaticFiles"),
});

}

注意事项:

  • UseDirectoryBrowser 和 UseStaticFiles 可能会泄密。建议不要在生产环境开启目录浏览。要小心那些被你开启了 UseStaticFiles 或 UseDirectoryBrowser 的目录,它们的子文件及子目录都可被访问。建议将公开内容放在<content root>/wwwroot 这样的目录中,远离应用程视图、配置文件等。

  • 使用 UseDirectoryBrowser 和 UseStaticFiles 暴露的文件的 URL是否区分大小写以及字符限制,受制于底层文件系统。比如Windows是不区分大小写的,但MACOS和Linux则区分大小写。


实战简单文件服务器

① 首先新建一个ASP.NETCore项目,选择空的模板。
② 使用NuGet命令添加Microsoft.AspNetCore.StaticFiles引用:

Install-PackageMicrosoft.AspNetCore.StaticFiles

③ 如果我们的文件服务器需要能访问和浏览E盘的所有文件与文件夹,那么我们就需要用到 UseStaticFiles和 UseDirectoryBrowser 方法了,在 Startup.Configure 方法下添加如下代码:

public void Configure(IApplicationBuilder app){
FileExtensionContentTypeProvider provider = new FileExtensionContentTypeProvider();
provider.Mappings[".log"] = "text/plain";
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(@"E:\"), // 指定静态文件目录
ServeUnknownFileTypes = true,
ContentTypeProvider = provider,
DefaultContentType = "
application/x-msdownload", // 设置未识别的MIME类型一个默认z值
});

app.UseDirectoryBrowser(new DirectoryBrowserOptions()
{
FileProvider = new PhysicalFileProvider(@"
E:\"), // 制定目录,这里指定 E盘,也可以是其他目录
});
}

然后运行程序,这里选择使用 Kestrel,访问:http://<ip>:5000/,如下图所示:

640?wx_fmt=png

640?wx_fmt=png

这样我们就能通过客户端浏览服务器E盘的所有文件及文件夹了。我们还手动设置了未识别的 MIME 类型一个默认值("application/x-msdownload"),当浏览器打开这些未识别类型的文件,就会下载这些文件。像 .log 这样的文件就被手动设置为文本方式,浏览器会直接展示出来。这样我们也就实现了一个简单的文件服务器。

如果想用局域网内其他电脑或手机查看图片或视频文件,则修改Properties文件下 launchSettings.json 配置文件中的应用程序URL就可以实现:

"WebApplication": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "https://*:5001;http://*:5000", // 这样就可以通过 http:ip:5000访问
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}

这样在同一局域网内,在手机上访问 http:ip:5000,就能访问服务器E盘中的文件了。

640?wx_fmt=png


参考原文

Microsoft 文档 ASP.NET Core 中间件
ASP.NET Core 中间件(Middleware)详解

原文地址:https://www.cnblogs.com/anayigeren/p/10282441.html

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com
640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/316607.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何使用vs将asp.net core项目添加容器支持并发布docker镜像到私有dockerhub和添加k8s/helm管理...

这篇文章介绍一下&#xff0c;如何使用VS2017给asp.net core添加容器支持&#xff0c;并发布镜像到私有docker hub&#xff0c;然后用chart管理容器镜像的操作流程。话不多说&#xff0c;just do it.新建项目首先新建一个asp.net core项目&#xff0c;这里我新建一个WebApi默认…

[小技巧]EF Core中如何获取上下文中操作过的实体

原文地址&#xff1a;https://www.cnblogs.com/lwqlun/p/10576443.html作者&#xff1a;Lamond Lu 源代码&#xff1a;https://github.com/lamondlu/EFCoreFindSample背景介绍当我们在工作单元(UnitOfWork)中使用EF/EF Core的时候&#xff0c;为了要保持事务&#xff0c;一个用…

IdentityServer4-前后端分离之Vue

前言之前文章讲到如何使用Node.jsExpress构建JavaScript客户端&#xff0c;实现前后端分离。本节将介绍如何使用Vue实现前后端分离&#xff0c;文中介绍Vue的知识比较基础&#xff0c;适合新手学习。一、搭建Vue项目前提条件&#xff1a;安装nodejs、webpack和vue-cli。这个网上…

P1850 [NOIP2016 提高组] 换教室

P1850 [NOIP2016 提高组] 换教室 题意&#xff1a; 有2n个课安排在n个时间段上&#xff0c;每个时间段上都有两个一样的课同时在不同地方上&#xff0c;起初牛牛被所有课都被安排在Ci上课&#xff0c;另一节课在Di上课。牛牛现在想跟换到Di位置&#xff0c;它最多可以申请m节…

ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署(三

在上文ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署&#xff08;二&#xff09;中&#xff0c;我介绍了如何使用Azure DevOps为ASP.NET Core应用程序案例&#xff1a;tasklist搭建持续集成环境。在持续集成的过程中&#xff0c;Azure DevOps的Build Pipeline会下…

ASP.NET Core开源Web应用程序框架ABP

"作为面向服务架构(SOA)的一个变体,微服务是一种将应用程序分解成松散耦合服务的新型架构风格. 通过细粒度的服务和轻量级的协议,微服务提供了更多的模块化,使应用程序更容易理解,开发,测试,并且更容易抵抗架构侵蚀. 它使小型团队能够开发,部署和扩展各自的服务,实现开发的…

CodeForces 1517G Starry Night Camping(网络流最小割)

CodeForces 1517G Starry Night Camping problem 洛谷链接 solution 这个平行四边形的脑洞我™真的长见识了 本题最离谱的要求就是&#xff1a;平行四边形的一条边平行于 xxx 轴。 而往往这种离谱要求就是正解的途径。(((φ(◎ロ◎;)φ))) 首先不观察也能知道&#xff0c…

Acwing 307. 连通图

Acwing 307. 连通图 题意&#xff1a; 求 N 个节点的无向连通图有多少个&#xff0c;节点有标号&#xff0c;编号为 1∼N。 例如下列图示&#xff0c;三个节点的无向连通图共 4 个。 题解: 用py写 代码&#xff1a; def c(n, m):n int(n)m int(m)ret 1for i in range(…

Acwing 309. 装饰围栏

Acwing 309. 装饰围栏 题意&#xff1a; 有n个模板&#xff0c;长度分别是1到N&#xff0c;现在按照高低交错的方式排列模板&#xff0c;能到的很多种排列的方案。 每个方案都可以写作一个长度为N的序列&#xff0c;序列中的个元素是木板的长度&#xff0c;把这些序列按照字典…

CodeForces 901D Weighting a Tree(结论)

problem 洛谷链接 注意&#xff1a;保证 C[v]C[v]C[v] 的奇偶性与顶点 vvv 的度的奇偶性相同。 solution 先考虑树的情况。这是个经典问题了&#xff0c;从叶子往上推&#xff0c;对于一个点还差的边权就有这个点和其父亲的边来补足。最后判断根是否满足条件即可。 那么怎…

CF938E Max History

CF938E Max History 题意&#xff1a; 我们定义f(a)为&#xff1a; 1、开始时&#xff0c;f(a)0,M1。 2、对于每个2<i<n,如果a[M]<a[i],那么f(a)f(a)a[M],Mi。 现在对于一个给定的数组a&#xff0c;求其所有排列的f(a)之和&#xff0c;答案对1e97取模。 题解&am…

CodeForces 1491G Switch and Flip(结论)

problem 洛谷链接 solution 弱化版&#xff1a;如果不考虑翻面&#xff0c;那就是转化为若干个环的问题了。 这里我们尝试用同样的思路解决。 首先明确几个硬币一次交换后的等价情况&#xff0c;如图&#xff08;灰色表示反面&#xff09; &#xff08;u→vu\rightarrow …

ASP.NET Core 借助 K8S 玩转容器编排

Production-Grade Container Orchestration - Automated container deployment, scaling, and management. 生产级别的容器编排系统——自动化的容器部署、扩展和管理。1. 引言由于最近在学习微服务&#xff0c;所以就基于之前docker的基础上把玩一下k8s&#xff08;Kubernetes…

CF1009E Intercity Travelling

CF1009E Intercity Travelling 题意&#xff1a; 有一段路程&#xff0c;路程可以看作是从0到n的一条直线 如果从起点出发或者从休息点出发&#xff0c;连续驾驶k千米&#xff0c;则需要消耗的体能为a1…ak 每个整点都有可能拥有一个休息点&#xff0c;每个休息点存在或者不存…

CodeForces 1396E Distance Matching(构造+树的重心+dfs+set)

problem 洛谷链接 solution 这种要求值和恰好为 kkk 的题目&#xff0c;一般要先明确值和的取值范围。 所以我们先来确定一下值和的最小值和最大值。 将一条路径拆成若干条边&#xff0c;单独计算每条边对路径的贡献。 假设一条边将树划分成 S,TS,TS,T 集合。因为 nnn 为…

程序员修神之路--

写在开始一般来说有两种策略用来在并发线程中进行通信&#xff1a;共享数据和消息传递。使用共享数据方式的并发编程面临的最大的一个问题就是数据条件竞争。处理各种锁的问题是让人十分头痛的一件事。传统多数流行的语言并发是基于多线程之间的共享内存&#xff0c;使用同步方…

Lawn of the Dead

Lawn of the Dead 题意&#xff1a; 有一个N * M的方格&#xff0c;我们从(1,1)出发&#xff0c;只能向右走或者向下走&#xff0c;存在一些障碍&#xff0c;问有多少格子是我们所能到达的 2<n,m,k<1e5 题解&#xff1a; 所有的点减去不能到达的点的个数&#xff0c;…

.Netcore 2.0 Ocelot Api网关教程(8)- 缓存

Ocelot中使用 CacheManager 来支持缓存&#xff0c;官方文档中强烈建议使用该包作为缓存工具。以下介绍通过使用CacheManager来实现Ocelot缓存。1、通过Nuget添加 Ocelot.Cache.CacheManager 包在OcelotGetway项目中添加引用&#xff1a;2、修改 Startup 中的 ConfigureService…

Acwing 273. 分级

Acwing 273. 分级 题意&#xff1a; 给定一个长度为N的序列A&#xff0c;现在构造一个长度为N的序列B&#xff0c;满足&#xff0c;B是非严格单增。最小化S∑i1N∣Ai−Bi∣\sum_{i1}^{N}|A_i-B_i|∑i1N​∣Ai​−Bi​∣ 题解&#xff1a; 引理&#xff1a; 一定存在一组最优…

.NET Core 给使用.NET的公司所带来的机遇

今晚在余晟的微信公众号看到了一篇文章《从.NET/C#开发的“后继无人”说起》。 这篇文章以从.NET/C#开发的“后继无人” 引出了推广极客时间的课程 刘超的《趣谈Linux操作系统》&#xff0c;通篇看下来这明显是刘超的《趣谈Linux操作系统》的软文。软文地址&#xff1a;https:/…