296 votes

ASP.NET MVC - Trouver le chemin absolu du dossier App_Data à partir du contrôleur

Quelle est la bonne façon de trouver le chemin absolu du dossier App_Data à partir d'un contrôleur dans un projet ASP.NET MVC ? J'aimerais pouvoir travailler temporairement avec un fichier .xml et je ne veux pas coder le chemin en dur.

Cela ne fonctionne pas :

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

        //.... do whatever 

        return View();
    }

}

Je pense qu'en dehors du contexte web, VirtualPathUtility.ToAbsolute() ne fonctionne pas. La chaîne de caractères path revient comme " C:\App_Data\somedata.xml "

Où dois-je déterminer le chemin du fichier .xml dans une application MVC ? global.asax et en faire une variable de niveau application ?

0 votes

Je suppose que dans un souci de séparation des préoccupations et de testabilité, VirtualPathUtility.ToAbsolute() ne devrait pas fonctionner. Mais alors, quelle est la bonne façon de procéder ?

416voto

eu-ge-ne Points 17847

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

Référence MSDN :

Méthode HttpServerUtility.MapPath

6 votes

@Cleiton Sauf que Url.Content donne une URL, pas un chemin de serveur.

8 votes

Pour mvc4 c'est seulement Server.MapPath()

0 votes

Je l'ai utilisé dans MVC3 et n'ai eu besoin que de HttpContext.Server.MapPath Ajout de Current a donné une erreur.

280voto

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

C'est probablement une façon plus "correcte" de procéder.

0 votes

Puis-je demander pourquoi ? Une brève explication serait la bienvenue.

25 votes

Parce qu'il n'y a pas de codage en dur de la chaîne "App_Data". Cela peut changer dans les futures versions, ou être différent dans Mono etc. etc.

20 votes

Ce qui est bien avec cette réponse, c'est que je peux l'utiliser dans mon projet de modèle. sans faisant référence à system.web, ce qui permet de garder une séparation nette. Bien joué !

146voto

Simon_Weaver Points 31141

J'essaie de prendre l'habitude d'utiliser HostingEnvironment au lieu de Server car il fonctionne aussi dans le contexte des services WCF.

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

6 votes

Server.MapPath() appelle finalement HostingEnvironment.MapPath(), cf. stackoverflow.com/questions/944219/

4 votes

C'est mon préféré car je peux l'utiliser en dehors de mes contrôleurs. C'est dans le System.Web.Hosting au cas où quelqu'un aurait besoin de connaître l'espace de nom pertinent. using . Réf : docs.microsoft.com/fr/us/dotnet/api/

9voto

Daniel Lidström Points 2970

La manière la plus correcte est d'utiliser HttpContext.Current.Server.MapPath("~/App_Data"); . Cela signifie que vous ne pouvez récupérer le chemin d'accès qu'à partir d'une méthode où l'option HttpContext est disponible. C'est logique : le répertoire App_Data est une structure de dossier de projet web [1].

Si vous avez besoin du chemin d'accès à ~/App_Data à partir d'une classe où vous n'avez pas accès à la classe HttpContext vous pouvez toujours injecter une interface de fournisseur en utilisant votre conteneur IoC :

public interface IAppDataPathProvider
{
    string GetAppDataPath();
}

Mettez-le en œuvre en utilisant votre HttpApplication :

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

MyHttpApplication.GetAppDataPath ressemble :

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

0 votes

Comment les statiques HttpContext.Current jamais pas être disponible à un endroit si vous l'utilisez - via un conteneur IoC - à un autre endroit ? Où la propriété statique ne serait-elle pas disponible ?

0 votes

Il ne sera disponible que dans le projet web. Cela répond-il à votre question ? Je ne suis pas sûr d'avoir bien compris. Aujourd'hui, je pense que j'aurais peut-être résolu ce problème (certes simple) de manière un peu différente. J'aurais probablement utilisé la même interface de fournisseur, mais en la configurant dans Application_Start avec le chemin racine de l'application.

0 votes

Non, HttpContext.Current n'est pas seulement disponible dans le projet web... Si vous référencez un projet qui possède GetAppDataPath(), il devra toujours référencer HttpContext.Current également. Par exemple, si vous utilisez la bibliothèque A qui utilise la bibliothèque B, votre application devra faire référence à la bibliothèque A. et B.

6voto

Rudy Lattae Points 674

Phil Haak propose un exemple qui, à mon avis, est un peu plus stable lorsqu'il s'agit de chemins comportant des séparateurs de répertoire de style "\". Il gère également la concaténation des chemins en toute sécurité. Il est fourni gratuitement dans System.IO

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

Cependant, vous pouvez également essayer "AppDomain.CurrentDomain.BaseDirector" au lieu de "Server.MapPath".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X