290
votes

What is the correct way to find the absolute path to the App_Data folder from a Controller in an ASP.NET MVC project? I'd like to be able to temporarily work with an .xml file and I don't want to hardcode the path.

This does not work:

[HandleError]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        string path = VirtualPathUtility.ToAbsolute("~/App_Data/somedata.xml");

        //.... do whatever 

        return View();
    }

}

I think outside of the web context VirtualPathUtility.ToAbsolute() doesn't work. string path comes back as "C:\App_Data\somedata.xml"

Where should I determine the path of the .xml file in an MVC app? global.asax and stick it an application-level variable?

8
I guess in a Seperation of Concerns & Testability sense - VirtualPathUtility.ToAbsolute() shouldn't work. But then what is the right way to do this?BuddyJoe

8 Answers

408
votes

ASP.NET MVC1 -> MVC3

string path = HttpContext.Current.Server.MapPath("~/App_Data/somedata.xml");

ASP.NET MVC4

string path = Server.MapPath("~/App_Data/somedata.xml");


HttpServerUtility.MapPath Method

277
votes
string path = AppDomain.CurrentDomain.GetData("DataDirectory").ToString();

This is probably a more "correct" way of getting it.

143
votes

I try to get in the habit of using HostingEnvironment instead of Server as it works within the context of WCF services too.

 HostingEnvironment.MapPath(@"~/App_Data/PriceModels.xml");
9
votes

The most correct way is to use HttpContext.Current.Server.MapPath("~/App_Data");. This means you can only retrieve the path from a method where the HttpContext is available. It makes sense: the App_Data directory is a web project folder structure [1].

If you need the path to ~/App_Data from a class where you don't have access to the HttpContext you can always inject a provider interface using your IoC container:

public interface IAppDataPathProvider
{
    string GetAppDataPath();
}

Implement it using your HttpApplication:

public class AppDataPathProvider : IAppDataPathProvider
{
    public string GetAppDataPath()
    {
        return MyHttpApplication.GetAppDataPath();
    }
}

Where MyHttpApplication.GetAppDataPath looks like:

public class MyHttpApplication : HttpApplication
{
    // of course you can fetch&store the value at Application_Start
    public static string GetAppDataPath()
    {
        return HttpContext.Current.Server.MapPath("~/App_Data");
    }
}

[1] http://msdn.microsoft.com/en-us/library/ex526337%28v=vs.100%29.aspx

6
votes

Phil Haak has an example that I think is a bit more stable when dealing with paths with crazy "\" style directory separators. It also safely handles path concatenation. It comes for free in System.IO

var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);

However, you could also try "AppDomain.CurrentDomain.BaseDirector" instead of "Server.MapPath".

5
votes
string filePath = HttpContext.Current.Server.MapPath("~/folderName/filename.extension");

OR

string filePath = HttpContext.Server.MapPath("~/folderName/filename.extension");
1
votes
string Index = i;
            string FileName = "Mutton" + Index + ".xml";
            XmlDocument xmlDoc = new XmlDocument();

            var path = Path.Combine(Server.MapPath("~/Content/FilesXML"), FileName);
            xmlDoc.Load(path); // Can use xmlDoc.LoadXml(YourString);

this is the best Solution to get the path what is exactly need for now

0
votes

This way i got the hosting path.

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;

namespace IHostingEnvironmentExample.Controllers
{
    public class HomeController : Controller
    {
        private IHostingEnvironment _env;
        public HomeController(IHostingEnvironment env)
        {
            _env = env;
        }
        public IActionResult Index()
        {
            var webRoot = _env.WebRootPath;
            var file = System.IO.Path.Combine(webRoot, "test.txt");
            System.IO.File.WriteAllText(file, "Hello World!");
            return View();
        }
    }
}

https://forums.asp.net/t/1696005.aspx?How+to+get+Local+Server+path+in+mvc