File.Exists()不适用于app.UseStaticFiles()

时间:2019-03-14 13:42:49

标签: c# asp.net-core

const pizzaSize = Object.freeze({ small: { key: 0, value: 25 }, medium: { key: 1, value: 35 }, large: { key: 2, value: 50 } })

当您使用静态文件夹时,File.Exists()似乎不起作用。 我的来源:

Startup.cs-Configure()

ASP.NET Core 2.2.0

app.UseStaticFiles(new StaticFileOptions() { FileProvider = new PhysicalFileProvider("C:\\TEMP"), RequestPath = PathString.FromUriComponent("/sub1/sub2") }); 中,我有一个文件C:\TEMP

当我打开test.txt时,我从https://localhost/sub1/sub2/test.txt获得了文件。到目前为止,一切都很好。

但是,如果我想检查文件是否存在,我总是会报错。使用这个:

C:\TEMP

有人解决方案如何检查静态文件上的文件存在吗?

2 个答案:

答案 0 :(得分:1)

如果您已阅读File.Exists方法的说明:

  

如果调用者具有所需的权限并且路径包含现有文件的名称,则为true;否则为true。否则为假。如果路径为null,无效路径或长度为零的字符串,则此方法还返回false。如果调用者没有足够的权限来读取指定的文件,则不会抛出异常,并且无论是否存在路径,该方法都将返回false。

它也表示以下内容:

  

不应将Exists方法用于路径验证,该方法仅检查path中指定的文件是否存在。将无效路径传递给Exists将返回false。若要检查路径是否包含任何无效字符,可以调用GetInvalidPathChars方法以检索对于文件系统无效的字符。您还可以创建一个正则表达式来测试该路径对于您的环境是否有效。有关可接受路径的示例,请参见File

因此,您的情况与此不符

答案 1 :(得分:0)

不确定为什么需要检测File.Exists,但是如果愿意,可以重用StaticFileOptionsFileProvider来检测文件是否存在。

创建如下的StaticFileDetector服务:

public class MyStaticFileOptions : StaticFileOptions { }

public class StaticFileDetector{

    private StaticFileOptions _sfo;

    public StaticFileDetector(IOptions<MyStaticFileOptions> sfo)
    {
        this._sfo = sfo.Value;
    }

    public bool FileExists(PathString path){

        // you might custom it as you like
        var baseUrl = this._sfo.RequestPath;

        // get the relative path
        PathString relativePath = null;
        if(!path.StartsWithSegments(baseUrl, out relativePath))
        {
            return false;
        }

        var file = this._sfo.FileProvider.GetFileInfo(relativePath.Value);
        return !file.IsDirectory && file.Exists;
    }
}

,然后将它们注册为服务:

public void ConfigureServices(IServiceCollection services)
{
    // ...

    services.Configure<MyStaticFileOptions>(o => {
        o.FileProvider = new PhysicalFileProvider("C:\\TEMP");
        o.RequestPath = PathString.FromUriComponent("/sub1/sub2");
    });
    services.AddSingleton<StaticFileDetector>()
}

最后,假设您要检测是否将处理请求路径:

    app.Use(async(ctx,next) => {
        var path = ctx.Request.Path;
        var detector = app.ApplicationServices.GetService<StaticFileDetector>();
        var exists = detector.FileExists(path);
        // now you know whether current request path exists or not. 
        await next();
    });

    app.UseStaticFiles();
    app.UseStaticFiles(app.ApplicationServices.GetService<IOptions<MyStaticFileOptions>>().Value);

    // ...

或者,如果您想在Controller中检测到某些路径,只需按如下所示注入此服务:

public class HomeController : Controller
{
    private StaticFileDetector _dector;

    public HomeController(StaticFileDetector dector)
    {
        this._dector = dector;
    }

    public IActionResult Index()
    {
        var path = new PathString("some-path-here");
        var x = this._dector.FileExists(path);
        return Json(x);
    }
}

[编辑] :避免直接使用File.Exists(unsafe_path_string),如果传递不安全的路径字符串,则不安全。