2010-04-07 5 views
13

Quiero resolver "~/whatever" desde contextos que no sean de página, como Global.asax (HttpApplication), HttpModule, HttpHandler, etc. pero solo puedo encontrar esos métodos de resolución específicos para los controles (y la página).¿Cómo puedo resolver las rutas de aplicación "~" de ASP.NET a la raíz del sitio web sin que esté presente un Control?

Creo que la aplicación debe tener el conocimiento suficiente para poder asignar esto fuera del contexto de la página. ¿No? O al menos tiene sentido para mí, debería resolverse en otras circunstancias, donde sea que se conozca la raíz de la aplicación.

Actualización: La razón es que estoy pegando "~" rutas en los archivos web.configuration, y quiero resolverlos desde los escenarios antes no controlados.

Actualización 2: Estoy tratando de resolverlos en la raíz del sitio web como Control.Resolve (..) comportamiento de la URL, no a una ruta del sistema de archivos.

+0

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

Respuesta

1

Puede hacerlo accediendo al objeto HttpContext.Current directamente:

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

Un punto a destacar es que, HttpContext.Current sólo va a ser no null en el contexto de una solicitud real. No está disponible en el evento Application_Stop, por ejemplo.

+3

Actualicé la pregunta porque estoy tratando de resolverla en una URL, no en el sistema de archivos. –

0

No he depurado este tonto, pero lo estoy lanzando allí como una solución manual por falta de encontrar un método Resolve en .NET Framework fuera de Control.

Esto funcionó en un "~/lo que sea" para mí.

/// <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

¿Cuál es el punto de las respuestas de la publicación 2 para la misma pregunta? –

0

En lugar de utilizar MapPath, trate de usar System.AppDomain.BaseDirectory. Para un sitio web, esta debería ser la raíz de su sitio web. Luego haga un System.IO.Path.Combine con lo que sea que vaya a pasar a MapPath sin el "~".

1

En Global.asax añadir lo siguiente:

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; 
    } 
} 
Cuestiones relacionadas