Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 940
Patryk Golebiowski Avatar asked Jun 04 '15 23:06

Patryk Golebiowski


2 Answers

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();
    }
like image 167
J. Lennon Avatar answered Nov 02 '22 14:11

J. Lennon


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.

like image 28
Alexander Christov Avatar answered Nov 02 '22 14:11

Alexander Christov