gpt4 book ai didi

c# - 在 wwwroot 之外提供静态文件,但在目录不存在时处理 PhysicalFileProvider

转载 作者:太空狗 更新时间:2023-10-29 23:36:29 29 4
gpt4 key购买 nike

我正在尝试从 wwwroot 外部提供文件,但还要处理目录可能尚不存在的设置情况。例如,如果我构建了一个依赖于此目录的站点,但用户没有按照安装说明先创建目录。

为了争论,假设我想要一个简单的网站,它有一个页面可以读取该目录的内容并显示一些文件。此页面还可能允许您从 /Documents 子目录下载文件。示例目录为 C:\Example\Documents

由于这是一个 aspnet core mvc 项目,我会在 Startup.cs 的 Configure 方法中使用 UseStaticFiles()

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory) {
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
} else {
app.UseExceptionHandler("/Home/Error");
}

app.UseStaticFiles();

// If C:/Example/Documents does not exist, an exception is thrown
// ArgumentException: The directory name C:\Example\Documents\ is invalid
// What is worse, the users is not directed to /Home/Error due to the application failing to properly start.
app.UseStaticFiles(new StaticFileOptions() {
FileProvider = new PhysicalFileProvider("C:/Example/Documents"),
RequestPath = new PathString("/Documents"),
});

app.UseMvc(routes => {
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}

现在我有一个两部分问题。如果在此方法中抛出异常,app.UseExceptionHandler("/Home/Error"); 似乎根本不生效。如果 PhysicalFileProvider 中使用的路径不存在,则会抛出内部服务器错误 500,然后页面显示应用程序启动失败消息。但是,如果我处于开发者模式,我确实会看到包含实际问题的开发者异常页面。我真的只是想制作一个友好的错误页面来处理这种情况。

问题的另一部分是当用户通过创建目录和添加内容来解决问题时会发生什么。创建后,他们将刷新页面。解决方法是强制关闭应用程序并重新启动它。理想情况下,我希望它能够自行恢复。我需要在 Controller 中执行 UseStaticHandle 部分吗?你能做到吗?当我尝试在我的 Controller 中对 IApplicationBuilder 使用依赖项注入(inject)时,我的尝试失败了,但我也没想到它会起作用。

老实说,我不确定处理此问题的最佳方法是什么。理想的情况是允许应用程序正常启动,这可以通过 Directory.Exists() 检查 PhysicalFileProvider 来完成,然后将错误转发给用户页面,但用户在解决问题后仍需要重新启动应用程序。

最佳答案

PhysicalFileProvider 抛出的异常:

System.ArgumentException: The directory name D:\Daten7\ is invalid.
Parameter name: path
at System.IO.FileSystemWatcher..ctor(String path, String filter)
at System.IO.FileSystemWatcher..ctor(String path)
at Microsoft.Extensions.FileProviders.PhysicalFileProvider.CreateFileWatcher(String root)
at Microsoft.Extensions.FileProviders.PhysicalFileProvider..ctor(String root)
at WebApplication1.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

In Startup.cs replace PhysicalFileProvider with PhysicalFileProvider2. Please find source code of PhysicalFileProvider2 below.

PhysicalFileProvider2的详细说明

ASP.Net core 的 PhysicalFileProvider 类坚持认为作为构造函数参数的目录在启动时已经存在,如果不存在则拒绝正常启动

我写了类 PhysicalFileProvider2 可以代替使用。即使目录不存在也可以实例化。但是在第一次调用它的任何方法时,如果目录尚不存在,则会创建该目录。现在启动正常,用户可以将文件添加到目录,然后可以正常提供。

public class PhysicalFileProvider2 : IFileProvider
{
private string root;
private PhysicalFileProvider physicalFileProvider;

public PhysicalFileProvider2(string root)
{
this.root = root;
}

private PhysicalFileProvider GetPhysicalFileProvider()
{
if (!File.Exists(root))
{
Directory.CreateDirectory(root);
}
if (physicalFileProvider == null)
{
physicalFileProvider = new PhysicalFileProvider(root);
}
return physicalFileProvider;
}

public IDirectoryContents GetDirectoryContents(string subpath)
{
return GetPhysicalFileProvider().GetDirectoryContents(subpath);
}

public IFileInfo GetFileInfo(string subpath)
{
return GetPhysicalFileProvider().GetFileInfo(subpath);
}

public IChangeToken Watch(string filter)
{
return GetPhysicalFileProvider().Watch(filter);
}
}

关于c# - 在 wwwroot 之外提供静态文件,但在目录不存在时处理 PhysicalFileProvider,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44526818/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com