ASP.NET MVC - denetleyicisinden App_Data klasörüne mutlak yol bulma


283

ASP.NET MVC projesinde bir Denetleyiciden App_Data klasörünün mutlak yolunu bulmak için doğru yol nedir? Geçici olarak bir .xml dosyası ile çalışabilmek istiyorum ve yolu kodlamak istemiyorum.

Bu çalışmıyor:

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

        //.... do whatever 

        return View();
    }

}

Web bağlamı dışında düşünüyorum VirtualPathUtility.ToAbsolute () çalışmıyor. dize yolu "C: \ App_Data \ somedata.xml" olarak geri gelir

Bir MVC uygulamasında .xml dosyasının yolunu nerede belirlemeliyim? global.asax ve uygulama düzeyinde bir değişken yapıştırmak?


Endişeler ve Testabilite bir anlamda sanırım - VirtualPathUtility.ToAbsolute () işe yaramaz. Peki bunu yapmanın doğru yolu nedir?
BuddyJoe

Yanıtlar:


399

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


MSDN Başvurusu:

HttpServerUtility.MapPath Yöntemi


6
@Cleiton Url.Content'ın bir sunucu yolu değil, bir URL vermesi dışında.
Andrew Dunkman

8
mvc4 için sadece Server.MapPath ()
SeriousM

6
MVC4 yolu işe yaramadı, ya kullanmak zorundaydım Currentya Server.MapPath(...)da SeriousM'ın belirttiği gibi.
gligoran

27
KullanımSystem.Web.Hosting.HostingEnvironment.MapPath()
Vince Panuccio

1
HttpContext.Current çağrıları, bir HttpContext (application_start etc)
bulunmayan

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

Bu muhtemelen onu elde etmenin daha "doğru" bir yoludur.


25
Çünkü "App_Data" dizesini kodlamak zor değil. Bu, gelecekteki versiyonlarda değişebilir veya Mono vs.'de farklı olabilir.
Alex

19
Bu cevapla ilgili güzel olan şey, bunu system.web'e başvurmadan Model projemde kullanabilmem, böylece temiz bir ayrılmanın korunmasına yardımcı olmasıdır. Güzel bir!
Frans

10
Pete'nin blog yazısı da bunu kullanmanın neden harika bir fikir olmayabilir?
Andy

13
MSDN'de belgelenmemiştir , bu nedenle kullanılmamalıdır.
Alexander Abramov

10
"App_Data" yerine başka bir dizenin sabit kodlanması "doğru" bir yol değildir. Ayrıca, .NET Core'da artık uygulama alanı yok.
UserControl

139

Ben kullanma alışkanlığı elde etmeye çalışmak HostingEnvironmentyerine Serverçok WCF hizmetleri kapsamında çalıştığı için.

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

6
Server.MapPath () nihayetinde HostingEnvironment.MapPath () öğesini çağırır, bkz. Stackoverflow.com/questions/944219/…
Todd

3
Bu benim favorim çünkü kontrolörlerimin dışında kullanabiliyorum. System.Web.Hostingİlgili kişinin bilmesi gerektiğinde bu ad alanındadır using. Referans: docs.microsoft.com/en-us/dotnet/api/…
MDMower

7

En doğru yol kullanmaktır HttpContext.Current.Server.MapPath("~/App_Data");. Bu, yolu yalnızcaHttpContext . Mantıklı: App_Data dizini bir web projesi klasör yapısıdır [1].

Erişiminiz olmayan bir sınıftan ~ / App_Data yoluna ihtiyacınız varsa HttpContext, IoC kabınızı kullanarak her zaman bir sağlayıcı arabirimi enjekte edebilirsiniz:

public interface IAppDataPathProvider
{
    string GetAppDataPath();
}

Aşağıdakileri kullanarak uygulayın HttpApplication:

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

Nereye MyHttpApplication.GetAppDataPathbenziyor:

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/tr-tr/library/ex526337%28v=vs.100%29.aspx


Nasıl statik olabilir HttpContext.Currenthiç değil bir IoC konteyner aracılığıyla - - Başka bir yerde bunu kullanıyorsanız tek bir yerde kullanılabilecek? Statik özellik nerede kullanılamaz?
M. Mimpen

Yalnızca web projesinde kullanılabilir. Bu sorunuza cevap veriyor mu? Tam olarak anladığımdan emin değilim. Bugün bu (kuşkusuz basit) sorunu biraz farklı çözmüş olabileceğimi düşünüyorum. Muhtemelen aynı sağlayıcı arayüzünü kullanacaktım ama Application_Start uygulamasında uygulama kök yolu ile ayarlayacağım.
Daniel Lidström

Hayır, HttpContext.Current yalnızca web projesinde kullanılamaz ... GetAppDataPath () içeren bir projeye başvurursanız, her zaman HttpContext.Current'a da başvurması gerekir. Yani, B kütüphanesini kullanan A kütüphanesini kullanırsanız, uygulamanızın A ve B kütüphanelerine referansları gerekecektir .
M. Mimpen

Bazen HttpContext'e doğrudan erişmemek, bunun yerine dolaylı bir seviyeden geçmek uygun olur. Örneğin birim testleri düşünün. Ahlaksızlık genellikle işleri bu şekilde yapmamın nedenidir. Ancak ifadenizle ilgili yanlış olduğunu düşünüyorum. Montajlar arasında yalnızca arabirimin paylaşılması gerekir. Bu yüzden testler için alay edebilirsiniz, yani testler için HttpContext.Current gerekmez. Senin için bir şeyler karıştırsam özür dilerim ...
Daniel Lidström

6

Phil Haak çılgın "\" tarzı dizin ayırıcılar ile yolları ele alırken biraz daha kararlı olduğunu düşünüyorum bir örnek var. Ayrıca yol birleştirme işlemlerini güvenle gerçekleştirir. System.IO'da ücretsiz olarak gelir

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

Ancak, "Server.MapPath" yerine "AppDomain.CurrentDomain.BaseDirector" da deneyebilirsiniz.


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

VEYA

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

1
Bu kod sorunun çözülmesine yardımcı olsa da, soruyu neden ve / veya nasıl cevapladığı konusunda ek bağlam sağlamak uzun vadeli değerini önemli ölçüde artıracaktır. Lütfen biraz açıklama eklemek için cevabınızı düzenleyin.
oɔɯǝɹ

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

şimdilik tam olarak ihtiyaç duyulan yolu elde etmek için en iyi çözüm budur

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.