29

Under ASP.NET and IIS, if I have a virtual path in the form "~/content", I can resolve this to a physical location using the MapPath method:

HttpContext.Server.MapPath("~/content");

How can you resolve a virtual paths to a physical location under an OWIN host?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Paul Turner
  • 38,949
  • 15
  • 102
  • 166

6 Answers6

33

You may use AppDomain.CurrentDomain.SetupInformation.ApplicationBase to get root of your application. With the root path, you can implement "MapPath" for Owin.

I do not know another way yet. (The ApplicationBase property is also used by Microsoft.Owin.FileSystems.PhysicalFileSystem.)

TN.
  • 18,874
  • 30
  • 99
  • 157
21

You shouldn't use HttpContext.Server as it's only available for MVC. HostingEnvironment.MapPath() is the way to go. However, it's not available for self-hosting owin. So, you should get it directly.

var path = HostingEnvironment.MapPath("~/content");
if (path == null)
{
    var uriPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
    path = new Uri(uriPath).LocalPath + "/content";
}
Boris Lipschitz
  • 9,236
  • 5
  • 53
  • 63
  • 1
    `HttpContext.Server` is part of System.Web.dll, so it's core to ASP.NET, not just the MVC pipeline. I'm afraid this doesn't really answer the question of how to resolve the path regardless of hosting environment; this only works within IIS. – Paul Turner Jul 15 '14 at 19:43
  • 2
    Not sure about namespaces, but Server.MapPath() requires HttpContext which is not used by WebApi. HostingEnvironment.MapPath() doesn't require HttpContext – Boris Lipschitz Jul 15 '14 at 23:30
  • 3
    HostingEnvironment is defined in the System.Web assembly too - it won't work outside of IIS. – Paul Turner Jun 09 '15 at 20:55
  • Outside IIS it will return null. Then you should be able to get it as in the code snippet – Boris Lipschitz Jun 19 '15 at 06:52
  • HostingEnvironment is a system.web.hosting class. I don't think this is included in self hosting environments – ton.yeung Jun 30 '15 at 16:52
  • In self hosted environment it would return null. Then it's just directly the file path. – Boris Lipschitz Jul 01 '15 at 07:38
  • Downvote, because `HostingEnvironment` requires the same dependency as `HttpContext`. The accepted answer seems to be the correct one in this usecase. – angularsen Sep 20 '15 at 12:34
  • 1
    under dnx & kestrel I found that both AppDomain.CurrentDomain.SetupInformation.ApplicationBase and Assembly.GetExecutingAssembly().GetName().CodeBase return the .dnx runtime folder - not the webapp root. var hostingEnvironment = app.ApplicationServices.GetService(); var realPath = hostingEnvironment.WebRootPath + ctx.Request.Path.Value; – brendanrichards Nov 04 '15 at 11:08
1

The Accepted answer, AppDomain.CurrentDomain.SetupInformation.ApplicationBase, did not work for me under dnx / kestrel - it returned the location of the .dnx runtime and not my webapp route.

This is what worked for me inside OWIN startup:

public void Configure(IApplicationBuilder app)
        {
        app.Use(async (ctx, next) =>
            {
                var hostingEnvironment = app.ApplicationServices.GetService<IHostingEnvironment>();
                var realPath = hostingEnvironment.WebRootPath + ctx.Request.Path.Value;

                // so something with the file here

                await next();
            });

            // more owin setup
        }
brendanrichards
  • 309
  • 2
  • 6
1

I'm adding another answer that would work for ASP.NET Core. There is a service IHostingEnvironment, and it's added by the framework.

public class ValuesController : Controller
{
    private IHostingEnvironment _env;

    public ValuesController(IHostingEnvironment env)
    {
        _env = env;
    }

    public IActionResult Get()
    {
        var webRoot = _env.WebRootPath;
        var file = Path.Combine(webRoot, "test.txt");
        File.WriteAllText(file, "Hello World!");
        return OK();
    }
}
Boris Lipschitz
  • 9,236
  • 5
  • 53
  • 63
1

I have an API running on OWIN self-host (no System.Web) - ran into this issue needing to load a text file where we maintain a list.

This worked for me, found from a co-worker - config.text is right in my root next to web.config:

var path = AppDomain.CurrentDomain.BaseDirectory + "/config.txt";
MrRobboto
  • 722
  • 3
  • 10
0

You may have few different implementations of function like

Func<string, string>

provided by different startup code under key like

"Host.Virtualization.MapPath"

and put it into OWIN dictionary. Or you can create basic class like this

public abstract class VirtualPathResolver { 
    string MapPath(string virtualPath);
}

and pick implementation either by configuration setting, command line parameter or environment variable.

Konstantin Isaev
  • 642
  • 8
  • 14