ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 在ASP.NET Core中设置app.UseFileServer后获取PhysicalPath

2019-06-27 19:05:06  阅读:1789  来源: 互联网

标签:c asp-net asp-net-core asp-net-core-mvc static-files


我有虚拟目录指向IIS中的一些文件服务器.我了解到ASP.NET Core无法“看到”IIS中的虚拟目录,因为它在Kestral上运行.

我被告知解决方法是使用app.UseFileServer:

app.UseFileServer(new FileServerOptions
{
    FileProvider = new PhysicalFileProvider(@"\\server\path"),
    RequestPath = new PathString("/MyPath"),
    EnableDirectoryBrowsing = true
});

我设置了它,当我在浏览器地址栏中键入/ MyPath时它可以工作.
但是,我希望能够在控制器中获得物理路径.

就像是:

//Server.Map path no longer exists in ASP.NET Core...
var filePath = Server.MapPath("/MyPath");
var fileName = "MyFile.txt";
System.IO.File.OpenRead(Path.Combine(filePath , fileName));

有没有办法通过在app.UseFileServer中提供RequestPath I设置来获取物理路径?

解决方法:

此问题的核心是访问控制器中正确的IFileProvider(指向目录的物理路径).

您可以通过在自定义服务中配置这些路径来实现此目的,以便您可以在任何位置访问它们:

>在Configure()方法中设置UseFileServer
>在您的控制器等

我有一些代码来演示如何解决这个问题:

服务和便利方法

首先,创建一个自定义服务,该服务将保存可由UseFileServer()或您的控制器访问的FileServerOptions.我选择了它们的列表,因此您可以添加多个路径.

public interface IFileServerProvider
{
    /// <summary>
    /// Contains a list of FileServer options, a combination of virtual + physical paths we can access at any time
    /// </summary>
    IList<FileServerOptions> FileServerOptionsCollection { get; }

    /// <summary>
    /// Gets the IFileProvider to access a physical location by using its virtual path
    /// </summary>
    IFileProvider GetProvider(string virtualPath);
}

/// <summary>
/// Implements IFileServerProvider in a very simple way, for demonstration only
/// </summary>
public class FileServerProvider : IFileServerProvider
{
    public FileServerProvider(IList<FileServerOptions> fileServerOptions)
    {
        FileServerOptionsCollection = fileServerOptions;
    }

    public IList<FileServerOptions> FileServerOptionsCollection { get; }

    public IFileProvider GetProvider(string virtualPath)
    {
        var options = FileServerOptionsCollection.FirstOrDefault(e => e.RequestPath == virtualPath);
        if (options != null)
            return options.FileProvider;

        throw new FileNotFoundException($"virtual path {virtualPath} is not registered in the fileserver provider");
    }
}

然后,为方便起见,您还可以添加一个Extension方法,该方法将使用上述服务中的选项调用UseFileServer中间件:

/// <summary>
/// Wrapper for UseFileServer to easily use the FileServerOptions registered in the IFileServerProvider
/// </summary>
public static class FileServerProviderExtensions
{
    public static IApplicationBuilder UseFileServerProvider(this IApplicationBuilder application, IFileServerProvider fileServerprovider)
    {
        foreach (var option in fileServerprovider.FileServerOptionsCollection)
        {
            application.UseFileServer(option);
        }
        return application;
    }
}

启动方法

现在,您只需要使用您选择的路径(1)注册IFileServerProvider,并将其移交给方便方法以实际使用它们(2).

(1)首先,使用您选择的路径将IFileServerProvider注册为Singleton服务:

public void ConfigureServices(IServiceCollection services)
{
    //Add our IFileServerProvider implementation as a singleton
    services.AddSingleton<IFileServerProvider>(new FileServerProvider(
        new List<FileServerOptions>
        {
            new FileServerOptions
            {
                FileProvider = new PhysicalFileProvider(@"D:\\somepath"),
                RequestPath = new PathString("/OtherPath"),
                EnableDirectoryBrowsing = true
            },
            new FileServerOptions
            {
                FileProvider = new PhysicalFileProvider(@"\\server\path"),
                RequestPath = new PathString("/MyPath"),
                EnableDirectoryBrowsing = true
            }
        }));

    // Add framework services.
    services.AddMvc();
}

(2)然后通过调用之前创建的扩展方法实际在UseFileServer中使用它们.请注意Configure方法中的额外参数IFileServerProvider fileServerprovider:

// Note: accessing the IFileServerProvider implemantion here by adding it 
// in the arguments list!
public void Configure(IApplicationBuilder app, IFileServerProvider fileServerprovider)
{
    //call convenience method which adds our FileServerOptions from 
    // the IFileServerProvider service
    app.UseFileServerProvider(fileServerprovider);

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

用法

现在,当您浏览到路径/ MyPath或/ OtherPath时,您应该像以前一样获得目录列表.

但是,因为我们在服务中拥有整洁的东西,所以现在可以更容易地在Controller中以编程方式访问这些路径:

public class HomeController : Controller
{
    private IFileServerProvider _fileServerProvider;

    public HomeController(IFileServerProvider fileServerProvider)
    {
        _fileServerProvider = fileServerProvider;
    }

    public IActionResult Index()
    {
        var fileProvider = _fileServerProvider.GetProvider("/MyPath");
        var fileInfo = fileProvider.GetFileInfo("MyFile.txt");
        using (var stream = System.IO.File.OpenRead(fileInfo.PhysicalPath))
        {
            string contents = new StreamReader(stream).ReadToEnd();
        }
        return View();
    }
}

这段代码可能是用更抽象,更充分命名的版本编写的,但它演示了一个解决问题的工作方案.

标签:c,asp-net,asp-net-core,asp-net-core-mvc,static-files
来源: https://codeday.me/bug/20190627/1307768.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有