ebvtrnog
ebvtrnog

Reputation: 4377

Reading a file in MVC 6

I want to access my create.sql file in the main folder of my server. It contains queries to set up my database. I have a problem to access this file at all.

1) I cannot really get there through Configuration. I can only use AddJsonFile, AddXmlFile, and AddIniFile. And I guess this is not the best idea to put a big sql file into any of those.

2) Mvc source on github seems to be missing MapPath. So no possibility of using Server.MapPath("~/create.sql").

How to achieve this then?

Upvotes: 8

Views: 7270

Answers (2)

Alexander Christov
Alexander Christov

Reputation: 10045

And also, instead of injecting IApplicationEnvironment you may use PlatformServices.Default.Application.ApplicationBasePath.

EDIT: Here's a possible implementation of MapPath/UnmapPath as extensions to PlatformServices:

removed (see EDIT2)

EDIT2: Slightly modified, IsPathMapped() added as well as some checks to see if path mapping/unmapping is really needed.

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 the actual execution path and in .net core 2.0, DEBUG mode it is xxx\bin\Debug\netcoreapp2.0, which, obviously is not what is required. Instead, replace PlatformServices with IHostingEnvironment and use environment.WebRootPath.

Upvotes: 5

J. Lennon
J. Lennon

Reputation: 3361

As already noticed and mentioned in the comments it seems that there is no MapPath in ASP.NET VNext (MVC 6). I found the workaround here:

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

Basically you need to get the ApplicationBasePath from IApplicationEnvironment interface, which currently is implemented as a service, following below the solution:

    private readonly IApplicationEnvironment _appEnvironment;

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

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

Upvotes: 16

Related Questions