Como posso resolver os caminhos do aplicativo ASP.NET “~” para o site Root sem um controle estar presente?

StackOverflow https://stackoverflow.com/questions/2589542

  •  25-09-2019
  •  | 
  •  

Pergunta

Eu quero resolver "~/qualquer coisa" de contextos internos de não páginas, como global.asax (httpplication), httpmodule, httphandler, etc., mas só posso encontrar métodos de resolução específicos para controles (e página).

Eu acho que o aplicativo deve ter conhecimento suficiente para poder mapear isso fora do contexto da página. Não? Ou pelo menos faz sentido para mim que deve ser resolvível em outras circunstâncias, onde quer que a raiz do aplicativo seja conhecida.

Atualizar: A razão é que estou mantendo os caminhos "~" nos arquivos Web.Configuration e deseja resolvê-los a partir dos cenários não controlados acima mencionados.

Atualização 2: Estou tentando resolvê -los na raiz do site, como controle.Resolve (..) Comportamento da URL, não para um caminho do sistema de arquivos.

Foi útil?

Solução

Aqui está a resposta:ASP.NET: Usando System.web.ui.control.resolveurl () em uma função compartilhada/estática

string absoluteUrl = VirtualPathUtility.ToAbsolute("~/SomePage.aspx");

Outras dicas

Você pode fazer isso acessando o HttpContext.Current objeto diretamente:

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

Um ponto a ser observado é que, HttpContext.Current só vai ser nãonull no contexto de uma solicitação real. Não está disponível no Application_Stop evento, por exemplo.

Em global.asax Adicione o seguinte:

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

Não depurei esse otário, mas estou jogando -o lá como uma solução manual para a falta de encontrar um método de resolução na estrutura .NET fora do controle.

Isso funcionou em um "~/qualquer coisa" para mim.

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

Em vez de usar o MAPPATH, tente usar o System.AppDomain.Basedirectory. Para um site, essa deve ser a raiz do seu site. Em seguida, faça um system.io.path.combine com o que você passaria para o Mappath sem o "~".

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top