ASP.NET MVC - найти абсолютный путь к папке App_Data из контроллера

Как правильно найти абсолютный путь к папке App_Data из контроллера в проекте ASP.NET MVC? Я хотел бы иметь возможность временно работать с файлом .xml и не хочу жестко указывать путь.

Это не работает:

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

        //.... do whatever 

        return View();
    }

}

Я думаю, что вне веб-контекста VirtualPathUtility.ToAbsolute () не работает. строковый путь возвращается как "C: \ App_Data \ somedata.xml"

Где мне определить путь к файлу .xml в приложении MVC? global.asax и вставить его в переменную уровня приложения?


person BuddyJoe    schedule 12.08.2009    source источник
comment
Я предполагаю, что в смысле разделения проблем и возможности тестирования - VirtualPathUtility.ToAbsolute () не должен работать. Но тогда как правильно это сделать?   -  person BuddyJoe    schedule 13.08.2009


Ответы (8)



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

Вероятно, это более «правильный» способ получить его.

person Alex from Jitbit    schedule 22.11.2010
comment
Могу я спросить, почему? Было бы неплохо дать краткое объяснение. - person winsmith; 26.05.2011
comment
Потому что это не жесткое кодирование строки App_Data. Это может измениться в будущих версиях или отличаться в Mono и т. Д. И т. Д. - person Alex from Jitbit; 27.05.2011
comment
В этом ответе хорошо то, что я могу использовать его в моем проекте модели без ссылки на system.web, что помогает сохранить четкое разделение. Хороший! - person Frans; 06.11.2011
comment
Отличный ответ, спасибо - это идеально подходит для поиска каталога App_Data из службы рабочего процесса WCF. - person David Clarke; 30.11.2011
comment
В этом сообщении блога объясняется это решение vaultofoughtts.net/GettingTheLocationOfAppDataFolder.aspx - person Pete Davis; 09.01.2012
comment
В сообщении в блоге, на которое ссылается Пит, также говорится о том, почему использование этого не может быть хорошей идеей. - person Andy; 06.04.2012
comment
Не задокументировано в MSDN, поэтому не следует использовать . - person Alexander Abramov; 10.04.2012
comment
Преимущество MapPath заключается в том, что вы можете смешивать свой полный путь, иначе вам придется использовать Path.Combine для создания пути, используя этот ответ здесь. - person Todd; 25.03.2014
comment
Хорошая вещь в жестком кодировании 'App_Data' (и я признаю, что ненавижу некоторые из этих строк) заключается в том, что любой, кто посмотрит этот код в будущем, сможет мгновенно увидеть, что он делает, - тогда как DataDirectory, скорее всего, может сбить с толку людей - person Simon_Weaver; 09.02.2015
comment
Жесткое кодирование другой строки вместо App_Data - неправильный способ. Кроме того, в .NET Core больше нет доменов приложений. - person UserControl; 23.09.2015
comment
Я считаю, что это правильный способ сделать это. Это работает, когда я запускаю update-database в консоли диспетчера пакетов, чтобы заполнить мою базу данных, используя данные из файла CSV в папке app_data. На этом этапе HttpContext отсутствует. Большое спасибо! - person user275801; 14.11.2016

Я стараюсь иметь привычку использовать HostingEnvironment вместо Server, поскольку это работает и в контексте служб WCF.

 HostingEnvironment.MapPath(@"~/App_Data/PriceModels.xml");
person Simon_Weaver    schedule 10.04.2010
comment
Server.MapPath () в конечном итоге вызывает HostingEnvironment.MapPath (), см. stackoverflow.com/questions/944219/ - person Todd; 25.03.2014
comment
Это мой любимый вариант, так как я могу использовать его вне своих контроллеров. Он находится в пространстве имен System.Web.Hosting на тот случай, если кому-то понадобится знать соответствующий using. Ссылка: docs.microsoft.com/en-us/ dotnet / api / - person MDMower; 18.02.2019

Самый правильный способ - использовать HttpContext.Current.Server.MapPath("~/App_Data");. Это означает, что вы можете получить путь только из метода, в котором доступен HttpContext. В этом есть смысл: каталог App_Data - это структура папок веб-проекта [1].

Если вам нужен путь к ~ / App_Data из класса, в котором у вас нет доступа к HttpContext, вы всегда можете внедрить интерфейс поставщика, используя свой контейнер IoC:

public interface IAppDataPathProvider
{
    string GetAppDataPath();
}

Реализуйте это с помощью своего HttpApplication:

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

Где MyHttpApplication.GetAppDataPath выглядит так:

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

person Daniel Lidström    schedule 23.10.2012
comment
Как может статический HttpContext.Current когда-либо не быть доступен в одном месте, если вы используете его - через контейнер IoC - в другом месте? Где статическое свойство было бы недоступно? - person M. Mimpen; 10.03.2015
comment
Он будет доступен только в веб-проекте. Отвечает ли это на ваш вопрос? Я не уверен, что полностью понимаю. Сегодня я думаю, что мог бы решить эту (по общему признанию простую) проблему немного по-другому. Я бы, вероятно, использовал тот же интерфейс поставщика, но установил его в Application_Start с корневым путем приложения. - person Daniel Lidström; 11.03.2015
comment
Нет, HttpContext.Current доступен не только в веб-проекте ... Если вы ссылаетесь на проект, который имеет GetAppDataPath (), он всегда будет также ссылаться на HttpContext.Current. Т.е. если вы используете библиотеку A, которая использует библиотеку B, вашему приложению потребуются ссылки на библиотеку A и B. - person M. Mimpen; 11.03.2015
comment
Иногда бывает удобно не обращаться к HttpContext напрямую, а пройти уровень косвенного обращения. Подумайте, например, о модульных тестах. Обычно я так поступаю благодаря тестируемости. Но я думаю, что вы ошиблись в своем заявлении. Между сборками должен использоваться только интерфейс. По этой причине вы можете имитировать его для тестов, т.е. вам не нужен HttpContext.Current для тестов. Извините, если я вас путаю ... - person Daniel Lidström; 12.03.2015

У Фила Хаака есть пример, который, на мой взгляд, более стабилен при работе с путями с сумасшедшими разделителями каталогов в стиле "\". Он также безопасно обрабатывает конкатенацию путей. Он поставляется бесплатно в System.IO

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

Однако вы также можете попробовать «AppDomain.CurrentDomain.BaseDirector» вместо «Server.MapPath».

person Rudy Lattae    schedule 16.11.2010

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);

это лучшее решение, чтобы получить то, что именно нужно сейчас

person Shahbaz Pirzada    schedule 07.12.2017

Таким образом я получил путь к хостингу.

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

person Babu Bhatt    schedule 21.07.2021

person    schedule
comment
Хотя этот код может помочь решить проблему, предоставление дополнительного контекста относительно того, почему и / или как он отвечает на вопрос, значительно улучшит его долгосрочную ценность. Пожалуйста, отредактируйте свой ответ, чтобы добавить пояснение. - person oɔɯǝɹ; 14.07.2016