在 MVC 6 中读取文件

Reading a file in MVC 6

我想访问我服务器主文件夹中的 create.sql 文件。它包含设置我的数据库的查询。我完全无法访问此文件。

1) 我真的无法通过 Configuration 到达那里。我只能使用 AddJsonFileAddXmlFileAddIniFile。而且我想这不是将大 sql 文件放入其中任何一个的最佳主意。

2) Mvc source on github 好像不见了 MapPath。所以不可能使用 Server.MapPath("~/create.sql").

那怎么实现呢?

正如已经注意到并在评论中提到的那样,ASP.NET VNext (MVC 6) 中似乎没有 MapPath。我在这里找到了解决方法:

http://forums.asp.net/t/2005166.aspx?HostingEnvironment+Equivalent+For+MapPath

基本上你需要从IApplicationEnvironment接口获取ApplicationBasePath,目前是作为服务实现的,下面是解决方案:

    private readonly IApplicationEnvironment _appEnvironment;

    public HomeController(IApplicationEnvironment appEnvironment)
    {
        _appEnvironment = appEnvironment;
    }

    public IActionResult Index()
    {
        var rootPath = _appEnvironment.ApplicationBasePath;
        return View();
    }

此外,您可以使用 PlatformServices.Default.Application.ApplicationBasePath.

而不是注入 IApplicationEnvironment

编辑:这是MapPath/UnmapPath作为PlatformServices的扩展的可能实现:

removed (see EDIT2)

EDIT2:略作修改,添加 IsPathMapped() 以及一些检查以查看是否确实需要路径 mapping/unmapping。

public static class PlatformServicesExtensions
{
    public static string MapPath(this PlatformServices services, string path)
    {
        var result = path ?? string.Empty;
        if (services.IsPathMapped(path) == false)
        {
            var wwwroot = services.WwwRoot();
            if (result.StartsWith("~", StringComparison.Ordinal))
            { 
                result = result.Substring(1); 
            }
            if (result.StartsWith("/", StringComparison.Ordinal))
            { 
                result = result.Substring(1);
            }
            result = Path.Combine(wwwroot, result.Replace('/', '\'));
        }

        return result;
    }

    public static string UnmapPath(this PlatformServices services, string path)
    {
        var result = path ?? string.Empty;
        if (services.IsPathMapped(path))
        {
            var wwwroot = services.WwwRoot();
            result = result.Remove(0, wwwroot.Length);
            result = result.Replace('\', '/');

            var prefix = (result.StartsWith("/", StringComparison.Ordinal) ? "~" : "~/");
            result = prefix + result;
        }

        return result;
    }

    public static bool IsPathMapped(this PlatformServices services, string path)
    {
        var result = path ?? string.Empty;
        return result.StartsWith(services.Application.ApplicationBasePath,
            StringComparison.Ordinal);
    }

    public static string WwwRoot(this PlatformServices services)
    {
        // todo: take it from project.json!!!
        var result = Path.Combine(services.Application.ApplicationBasePath, "wwwroot");
        return result;
    }
}

EDIT3: PlatformServices.WwwRoot() return 实际执行路径在.net core 2.0中,DEBUG模式是xxx\bin\Debug\netcoreapp2.0,这显然不是所需要的。相反,将 PlatformServices 替换为 IHostingEnvironment 并使用 environment.WebRootPath.