2010-04-07 13 views
13

Je veux résoudre "~/quoi" de l'intérieur de contextes non-Page tels que Global.asax (HttpApplication), HttpModule, HttpHandler, etc. mais ne peut trouver que de telles méthodes de résolution spécifiques à Controls (et Page).Comment puis-je résoudre les chemins d'accès "~" d'ASP.NET à la racine du site Web sans qu'un contrôle soit présent?

Je pense que l'application devrait avoir suffisamment de connaissances pour être en mesure de mapper cela en dehors du contexte de la page. Non? Ou au moins, il est logique pour moi que cela puisse être résolu dans d'autres circonstances, partout où la racine de l'application est connue.

Mise à jour: La raison d'être, je suis coller « ~ » chemins dans les fichiers web.configuration, et que vous voulez les résoudre des scénarios susmentionnés non-contrôle.

Mise à jour 2: J'essaie de les résoudre à la racine du site Web, comme le comportement de l'URL Control.Resolve (..), pas à un chemin de système de fichiers.

+0

dupliquée: http://stackoverflow.com/questions/26796/asp-net-using-system-web-ui-control-resolveurl-in- a-shared-static-function –

Répondre

1

Vous pouvez le faire en accédant à l'objet HttpContext.Current directement:

var resolved = HttpContext.Current.Server.MapPath("~/whatever") 

Un point à noter est que, HttpContext.Current va seulement être non null dans le cadre d'une demande réelle. Il n'est pas disponible dans l'événement Application_Stop, par exemple.

+3

J'ai mis à jour la question parce que j'essaie de résoudre une URL, pas le système de fichiers. –

0

Je n'ai pas débogué cette ventouse mais je l'ai jetée ici en tant que solution manuelle faute de trouver une méthode Resolve dans le .NET Framework en dehors de Control.

Cela a fonctionné sur un "~/quoi" pour moi.

/// <summary> 
/// Try to resolve a web path to the current website, including the special "~/" app path. 
/// This method be used outside the context of a Control (aka Page). 
/// </summary> 
/// <param name="strWebpath">The path to try to resolve.</param> 
/// <param name="strResultUrl">The stringified resolved url (upon success).</param> 
/// <returns>true if resolution was successful in which case the out param contains a valid url, otherwise false</returns> 
/// <remarks> 
/// If a valid URL is given the same will be returned as a successful resolution. 
/// </remarks> 
/// 
static public bool TryResolveUrl(string strWebpath, out string strResultUrl) { 

    Uri uriMade = null; 
    Uri baseRequestUri = new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority)); 

    // Resolve "~" to app root; 
    // and create http://currentRequest.com/webroot/formerlyTildeStuff 
    if (strWebpath.StartsWith("~")) { 
     string strWebrootRelativePath = string.Format("{0}{1}", 
      HttpContext.Current.Request.ApplicationPath, 
      strWebpath.Substring(1)); 

     if (Uri.TryCreate(baseRequestUri, strWebrootRelativePath, out uriMade)) { 
      strResultUrl = uriMade.ToString(); 
      return true; 
     } 
    } 

    // or, maybe turn given "/stuff" into http://currentRequest.com/stuff 
    if (Uri.TryCreate(baseRequestUri, strWebpath, out uriMade)) { 
     strResultUrl = uriMade.ToString(); 
     return true; 
    } 

    // or, maybe leave given valid "http://something.com/whatever" as itself 
    if (Uri.TryCreate(strWebpath, UriKind.RelativeOrAbsolute, out uriMade)) { 
     strResultUrl = uriMade.ToString(); 
     return true; 
    } 

    // otherwise, fail elegantly by returning given path unaltered.  
    strResultUrl = strWebpath; 
    return false; 
} 
0
public static string ResolveUrl(string url) 
{ 
    if (string.IsNullOrEmpty(url)) 
    { 
     throw new ArgumentException("url", "url can not be null or empty"); 
    } 
    if (url[0] != '~') 
    { 
     return url; 
    } 
    string applicationPath = HttpContext.Current.Request.ApplicationPath; 
    if (url.Length == 1) 
    { 
     return applicationPath; 
    } 
    int startIndex = 1; 
    string str2 = (applicationPath.Length > 1) ? "/" : string.Empty; 
    if ((url[1] == '/') || (url[1] == '\\')) 
    { 
     startIndex = 2; 
    } 
    return (applicationPath + str2 + url.Substring(startIndex)); 
} 
+0

Quel est le but des réponses post-2 pour la même question? –

0

Au lieu d'utiliser MapPath, essayez d'utiliser System.AppDomain.BaseDirectory. Pour un site Web, cela devrait être la racine de votre site Web. Ensuite, faites un System.IO.Path.Combine avec tout ce que vous alliez passer à MapPath sans le "~".

1

Dans Global.asax ajouter ce qui suit:

private static string ServerPath { get; set; } 

protected void Application_BeginRequest(Object sender, EventArgs e) 
{ 
    ServerPath = BaseSiteUrl; 
} 

protected static string BaseSiteUrl 
{ 
    get 
    { 
     var context = HttpContext.Current; 
     if (context.Request.ApplicationPath != null) 
     { 
      var baseUrl = context.Request.Url.Scheme + "://" + context.Request.Url.Authority + context.Request.ApplicationPath.TrimEnd('/') + '/'; 
      return baseUrl; 
     } 
     return string.Empty; 
    } 
}