it-swarm.com.de

Absolute URL vom relativen Pfad abrufen (refactored-Methode)

Ich bin wirklich überrascht, dass es keine native .NET-Methode gibt, um eine absolute URL von einer relativen URL zu erhalten. Ich weiß, dass dies viele Male diskutiert wurde, aber noch nie eine befriedigende Methode gefunden hat, mit der dies gut funktioniert. Können Sie uns helfen, die Methode unten einzustellen?

Ich denke, alles, was ich noch brauche, ist, das Protokoll automatisch auszuwählen, anstatt es fest zu kodieren (http/https). Was fehlt mir sonst noch (Vorbehalte, Leistung usw.)?

public static string GetAbsoluteUrl(string url)
    {
        //VALIDATE INPUT FOR ALREADY ABSOLUTE URL
        if (url.StartsWith("http://", StringComparison.OrdinalIgnoreCase) 
           || url.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
        { 
            return url;
        }

        //GET PAGE REFERENCE FOR CONTEXT PROCESSING
        Page page = HttpContext.Current.Handler as Page;

        //RESOLVE PATH FOR APPLICATION BEFORE PROCESSING
        if (url.StartsWith("~/"))
        {
            url = page.ResolveUrl(url);
        }

        //BUILD AND RETURN ABSOLUTE URL
        return "http://" + page.Request.ServerVariables["SERVER_NAME"] + "/" 
                         + url.TrimStart('/');
    }
53
TruMan1

Dies war immer meine Herangehensweise an dieses kleine Ärgernis. Beachten Sie die Verwendung von VirtualPathUtility.ToAbsolute (relativeUrl) , damit die Methode als Erweiterung in einer statischen Klasse deklariert werden kann.

/// <summary>
/// Converts the provided app-relative path into an absolute Url containing the 
/// full Host name
/// </summary>
/// <param name="relativeUrl">App-Relative path</param>
/// <returns>Provided relativeUrl parameter as fully qualified Url</returns>
/// <example>~/path/to/foo to http://www.web.com/path/to/foo</example>
public static string ToAbsoluteUrl(this string relativeUrl) {
    if (string.IsNullOrEmpty(relativeUrl))
        return relativeUrl;

    if (HttpContext.Current == null)
        return relativeUrl;

    if (relativeUrl.StartsWith("/"))
        relativeUrl = relativeUrl.Insert(0, "~");
    if (!relativeUrl.StartsWith("~/"))
        relativeUrl = relativeUrl.Insert(0, "~/");

    var url = HttpContext.Current.Request.Url;
    var port = url.Port != 80 ? (":" + url.Port) : String.Empty;

    return String.Format("{0}://{1}{2}{3}",
        url.Scheme, url.Host, port, VirtualPathUtility.ToAbsolute(relativeUrl));
}
85
Nathan Taylor
new System.Uri(Page.Request.Url, "/myRelativeUrl.aspx").AbsoluteUri
64
g.breeze

Dieser arbeitet für mich ...

new System.Uri(Page.Request.Url, ResolveClientUrl("~/mypage.aspx")).AbsoluteUri
10
Carter Medlin

Bei ASP.NET müssen Sie den Referenzpunkt für eine "relative URL" berücksichtigen - ist dies relativ zur Seitenanforderung ein Benutzersteuerelement oder ist es "relativ", nur weil "~ /" verwendet wird?

Die Uri-Klasse enthält eine einfache Methode zum Konvertieren einer relativen URL in eine absolute URL (unter Angabe einer absoluten URL als Referenzpunkt für die relative URL):

var uri = new Uri(absoluteUrl, relativeUrl);

Wenn relativeUrl tatsächlich eine absolute URL ist, wird die absoluteUrl ignoriert.

Es bleibt nur die Frage, was der Bezugspunkt ist und ob "~ /" URLs erlaubt sind (der Uri-Konstruktor übersetzt diese nicht).

5
Stephen Cleary

Hier ist meine eigene Version, die viele Validierungen und relative Pfadangaben von der aktuellen Standortoption des Benutzers verarbeitet. Fühlen Sie sich frei von hier zu refactor :)

/// <summary>
/// Converts the provided app-relative path into an absolute Url containing 
/// the full Host name
/// </summary>
/// <param name="relativeUrl">App-Relative path</param>
/// <returns>Provided relativeUrl parameter as fully qualified Url</returns>
/// <example>~/path/to/foo to http://www.web.com/path/to/foo</example>
public static string GetAbsoluteUrl(string relativeUrl)
{
    //VALIDATE INPUT
    if (String.IsNullOrEmpty(relativeUrl))
        return String.Empty;
    //VALIDATE INPUT FOR ALREADY ABSOLUTE URL
    if (relativeUrl.StartsWith("http://", StringComparison.OrdinalIgnoreCase) 
    || relativeUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
        return relativeUrl;
    //VALIDATE CONTEXT
    if (HttpContext.Current == null)
        return relativeUrl;
    //GET CONTEXT OF CURRENT USER
    HttpContext context = HttpContext.Current;
    //FIX ROOT PATH TO APP ROOT PATH
    if (relativeUrl.StartsWith("/"))
        relativeUrl = relativeUrl.Insert(0, "~");
    //GET RELATIVE PATH
    Page page = context.Handler as Page;
    if (page != null)
    {
        //USE PAGE IN CASE RELATIVE TO USER'S CURRENT LOCATION IS NEEDED
        relativeUrl = page.ResolveUrl(relativeUrl);
    }
    else //OTHERWISE ASSUME WE WANT ROOT PATH
   {
        //PREPARE TO USE IN VIRTUAL PATH UTILITY
        if (!relativeUrl.StartsWith("~/"))
            relativeUrl = relativeUrl.Insert(0, "~/");
        relativeUrl = VirtualPathUtility.ToAbsolute(relativeUrl);
    }

    var url = context.Request.Url;
    var port = url.Port != 80 ? (":" + url.Port) : String.Empty;
    //BUILD AND RETURN ABSOLUTE URL
    return String.Format("{0}://{1}{2}{3}",
           url.Scheme, url.Host, port, relativeUrl);
}
3
Basem

Wenn Sie sich im Kontext eines MVC-Controllers oder einer Ansicht befinden, können Sie den UrlHelper verwenden, der nur über Url zugänglich sein sollte.

Url.Content("~/content/images/myimage.jpg")

Welches vollständig auf /virtual_directoryname/content/images/myimage.jpg erweitert wird

Dies kann in einer Controller- oder CSHML-Datei verwendet werden

Ja, es ist ein bisschen merkwürdig, dass es Content heißt, aber es soll verwendet werden, um einen absoluten Pfad zu einer Ressource zu erhalten, so dass es sinnvoll ist

1
Simon_Weaver

Immer noch nicht gut genug mit einheimischen Sachen. Hier ist was ich endete mit:

public static string GetAbsoluteUrl(string url)
{
    //VALIDATE INPUT
    if (String.IsNullOrEmpty(url))
    {
        return String.Empty;
    }

    //VALIDATE INPUT FOR ALREADY ABSOLUTE URL
    if (url.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || url.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
    { 
        return url;
    }

    //GET CONTEXT OF CURRENT USER
    HttpContext context = HttpContext.Current;

    //RESOLVE PATH FOR APPLICATION BEFORE PROCESSING
    if (url.StartsWith("~/"))
    {
        url = (context.Handler as Page).ResolveUrl(url);
    }

    //BUILD AND RETURN ABSOLUTE URL
    string port = (context.Request.Url.Port != 80 && context.Request.Url.Port != 443) ? ":" + context.Request.Url.Port : String.Empty;
    return context.Request.Url.Scheme + Uri.SchemeDelimiter + context.Request.Url.Host + port + "/" + url.TrimStart('/');
}
1
TruMan1

Überprüfen Sie den folgenden Code, um die absolute URL abzurufen:

Page.Request.Url.AbsoluteUri

Ich hoffe nützlich zu sein.

0
DEVMBM

Die letzte Version, die sich um alle vorherigen Beschwerden kümmert (Ports, logische URL, relative URL, vorhandene absolute URL ... usw.) unter Berücksichtigung Der aktuelle Handler ist die Seite:

public static string ConvertToAbsoluteUrl(string url)
{
    if (!IsAbsoluteUrl(url))
    {
        if (HttpContext.Current != null && HttpContext.Current.Request != null && HttpContext.Current.Handler is System.Web.UI.Page)
        {
            var originalUrl = HttpContext.Current.Request.Url;
            return string.Format("{0}://{1}{2}{3}", originalUrl.Scheme, originalUrl.Host, !originalUrl.IsDefaultPort ? (":" + originalUrl.Port) : string.Empty, ((System.Web.UI.Page)HttpContext.Current.Handler).ResolveUrl(url));
        }
        throw new Exception("Invalid context!");
    }
    else
        return url;
}

private static bool IsAbsoluteUrl(string url)
{
    Uri result;
    return Uri.TryCreate(url, UriKind.Absolute, out result);
}
0
yazanpro

Wenn Sie eine URL aus Ihrer Business Logic-Schicht generieren möchten, können Sie nicht die Flexibilität haben, die Seitenklasse von ASP.NET-Webformular/ResolveUrl des Steuerelements (..) usw. zu verwenden. Darüber hinaus müssen Sie möglicherweise eine URL aus ASP.NET generieren MVC-Controller auch, wenn Sie nicht nur die ResolveUrl (..) -Methode des Web Forms vermissen, sondern auch die Url.Action (..) nicht abrufen können, obwohl Url.Action nur den Controller-Namen und den Aktionsnamen und nicht die relative URL verwendet . 

Ich habe es versucht 

var uri = neuer Uri (absoluteUrl, relativeUrl)

ansatz, aber es gibt auch ein Problem. Wenn die Webanwendung in einem virtuellen Verzeichnis IIS gehostet wird, in dem die URL der App wie folgt lautet: http://localhost/MyWebApplication1/ und die relative URL "/ myPage", wird die relative URL in "http://localhost/MyPage" aufgelöst ein weiteres Problem.

Um solche Probleme zu überwinden, habe ich deshalb eine UrlUtils-Klasse geschrieben, die von einer Klassenbibliothek aus arbeiten kann. Es hängt also nicht von der Page-Klasse ab, sondern von ASP.NET MVC. Wenn Sie also nichts dagegen haben, Ihrem Klassenbibliothekprojekt einen Verweis auf die MVC-DLL hinzuzufügen, funktioniert meine Klasse problemlos. Ich habe getestet in IIS Szenario eines virtuellen Verzeichnisses, in dem die URL der Webanwendung folgendermaßen lautet: http://localhost/MyWebApplication/MyPage. Mir wurde klar, dass wir manchmal sicherstellen müssen, dass es sich bei der absoluten URL um eine SSL-URL oder um eine nicht-SSL-URL handelt. Also habe ich meine Klassenbibliothek geschrieben, die diese Option unterstützt. Ich habe diese Klassenbibliothek eingeschränkt, sodass die relative URL eine absolute URL oder eine relative URL sein kann, die mit '~ /' beginnt. 

Mit dieser Bibliothek kann ich anrufen

string absoluteUrl = UrlUtils.MapUrl("~/Contact");

Gibt zurück: http://localhost/Contact Wenn die Seiten-URL lautet: http://localhost/Home/About

Gibt zurück: http://localhost/MyWebApplication/Contact Wenn die Seiten-URL lautet: http://localhost/MyWebApplication/Home/About

  string absoluteUrl = UrlUtils.MapUrl("~/Contact", UrlUtils.UrlMapOptions.AlwaysSSL);

Gibt zurück: **https**://localhost/MyWebApplication/Contact Wenn die Seiten-URL lautet: http://localhost/MyWebApplication/Home/About

Hier ist meine Klassenbibliothek:

 public class UrlUtils
    {
        public enum UrlMapOptions
        {
            AlwaysNonSSL,
            AlwaysSSL,
            BasedOnCurrentScheme
        }

        public static string MapUrl(string relativeUrl, UrlMapOptions option = UrlMapOptions.BasedOnCurrentScheme)
        {
            if (relativeUrl.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
                relativeUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
                return relativeUrl;

            if (!relativeUrl.StartsWith("~/"))
                throw new Exception("The relative url must start with ~/");

            UrlHelper theHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);

            string theAbsoluteUrl = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) +
                                           theHelper.Content(relativeUrl);

            switch (option)
            {
                case UrlMapOptions.AlwaysNonSSL:
                    {
                        return theAbsoluteUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase)
                            ? string.Format("http://{0}", theAbsoluteUrl.Remove(0, 8))
                            : theAbsoluteUrl;
                    }
                case UrlMapOptions.AlwaysSSL:
                    {
                        return theAbsoluteUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase)
                            ? theAbsoluteUrl
                            : string.Format("https://{0}", theAbsoluteUrl.Remove(0, 7));
                    }
            }

            return theAbsoluteUrl;
        }
    }   
0
Emran Hussain