Abrufen der absoluten URL aus einer ASP.NET MVC-Aktion

77

Dies ist wahrscheinlich eine Scheinfrage, aber ich kann keinen klaren Hinweis finden. Ich habe eine POCO-Klasse in einer MVC3-Webanwendung, deren einziger Zweck darin besteht, die Sicherung einiger Dateien auf dem Server zu verwalten. In der Regel wird ein Backup erstellt und der Dateiname an den Controller zurückgegeben, der eine E-Mail mit der URL zum Herunterladen sendet. Dies funktioniert gut, aber ich kann nicht die absolute URL erstellen, die gesendet werden soll. Unabhängig davon , welche Funktion ich verwende, erhalte ich immer eine relative URL wie /Backup/TheFile.zip und nicht z . B. http://www.somesite.com/Backup/TheFile.zip . Ich habe es versucht:

VirtualPathUtility.ToAbsolute("~/Backup/SomeFile.zip");
HttpRuntime.AppDomainAppVirtualPath + "/Backup/SomeFile.zip";
Url.Content("~/Backup/SomeFile.zip");

aber sie alle geben so etwas wie /Backup/SomeFile.zip zurück . Irgendeine Idee?

Naftis
quelle
1
Die Antwort hier hat mir in einem ähnlichen Szenario geholfen. Diese Antwort richtet sich sowohl an http / https als auch an Portnummern. Dies ist sehr nützlich, da sich meine lokale Entwicklung auf http mit einer Portnummer befindet, die Produktionslösung jedoch auf https.
Sujeewa

Antworten:

117

Sie können dies folgendermaßen tun:

var urlBuilder =
    new System.UriBuilder(Request.Url.AbsoluteUri)
        {
            Path = Url.Action("Action", "Controller"),
            Query = null,
        };

Uri uri = urlBuilder.Uri;
string url = urlBuilder.ToString();
// or urlBuilder.Uri.ToString()

Anstelle Url.Action()dieses Beispiels können Sie auch eine Url.Content()beliebige Routing-Methode verwenden oder einfach nur einen Pfad übergeben.

Wenn die URL jedoch zu a wechselt Controller Action, gibt es einen kompakteren Weg:

var contactUsUriString =
    Url.Action("Contact-Us", "About",
               routeValues: null /* specify if needed */,
               protocol: Request.Url.Scheme /* This is the trick */);

Der Trick dabei ist, dass protocolSie eine absolute URL erhalten , sobald Sie beim Aufrufen einer Routing-Methode das / -Schema angeben . Ich empfehle diese, wenn möglich , aber Sie haben auch die allgemeinere Methode im ersten Beispiel, falls Sie sie benötigen.

Ich habe hier ausführlich darüber gebloggt:
http://gurustop.net/blog/2012/03/23/writing-absolute-urls-to-other-actions-in-asp-net-mvc/

Auszug aus Meligys AngularJS & Web Dev Goodies Newsletter

Meligy
quelle
Bearbeitet: Wenn Ihre Anfrage Uri ein Abfragesegment hatte, müssen Sie möglicherweise auch die Query-Eigenschaft im Uri-Builder überschreiben!
Tim Lovell-Smith
Hier ist eine kurze
Ben Cull
35

Aus dem Controller heraus:

var path = VirtualPathUtility.ToAbsolute(pathFromPoco);
var url = new Uri(Request.Url, path).AbsoluteUri
Chris
quelle
1
VirtualPathUtility gibt weiterhin einen relativen Uri im MVC4-Controller zurück
Maksim Vi.
6
Und in Kombination mit der Uri-Klasse ist das alles, was Sie brauchen. Eine Art sinnloser Kommentar.
Chris
Ich würde zuerst Ihren Pfad durch die Url.Content () -Methode übergeben. Diese Antwort schlägt für nicht absolute Pfade fehl (beginnen Sie mit '/').
Neil Monroe
19

Das funktioniert bei mir:

using System;
using System.Web;
using System.Web.Mvc;

public static class UrlExtensions
{
    public static string Content(this UrlHelper urlHelper, string contentPath, bool toAbsolute = false)
    {
        var path = urlHelper.Content(contentPath);
        var url = new Uri(HttpContext.Current.Request.Url, path);

        return toAbsolute ? url.AbsoluteUri : path;
    }
}

Verwendung in cshtml:

@Url.Content("~/Scripts/flot/jquery.flot.menuBar.js", true)
Jeff Tian
quelle
Das ist toll. Ich habe tatsächlich fast genau das geschrieben, was Sie in Ihrer Antwort vorgeschlagen haben, aber nicht daran gedacht, es als Überschreibung für die Content-Methode hinzuzufügen, um es noch schlanker zu machen. Vielen Dank!
Neil Monroe
Vielen Dank für die wunderbare Lösung. Ich verwende die ng-include-Direktive und hatte aufgrund relativer Pfade viele Probleme. Das einzige, was ich in Ihrem Code hinzugefügt habe, ist die URL.
FrenkyB
4

Die in MVC 4 integrierten Helfer erstellen absolute URLs, wenn die Parameter hostoder protocolnicht leer sind. Sehen Sie diese Antwort hier mit einem Beispiel Verlängerungsverfahren zur Verwendung in Aussicht.

Carl G.
quelle
1

In ASP.Net Core 2.0 (MVC) erstellt dies eine absolute URL für eine Aktion.

var url = Url.Action("About", "Home", new { /*Route values here*/ }, Request.Scheme);
brady321
quelle
0

Ich habe dafür eine Hilfsklasse für MVC 5 geschrieben ... Sie ist ziemlich flexibel und besonders nützlich, wenn Sie diese Funktionalität benötigen, wenn Sie sich nicht in einem Controller befinden. Sie sollten es direkt in ein Projekt einfügen und loslegen können.

Wie Meligy betonte, besteht der Schlüssel darin, das Protokoll einzuschließen. Hier habe ich es fest als http codiert. Wenn Sie also SSL verwenden möchten, muss dies möglicherweise etwas flexibler werden.

public class AbsoluteUrlHelper
{
    /// <summary>
    /// Creates an absolute "fully qualified" url from an action, and assumes the current controller.
    /// </summary>
    /// <returns></returns>
    public static string GetAbsoluteUrl(string action, object routeValues = null)
    {
        var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
        var values = urlHelper.RequestContext.RouteData.Values;
        var controller = values["controller"].ToString();

        return GetAbsoluteUrl(action, controller, urlHelper, routeValues);
    }

    /// <summary>
    /// Creates an absolute "fully qualified" url from an action and controller.
    /// </summary>
    public static string GetAbsoluteUrl(string action, string controller, object routeValues = null)
    {
        var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);

        return GetAbsoluteUrl(action, controller, urlHelper, routeValues);
    }

    /// <summary>
    /// Creates an absolute "fully qualified" url from an action and controller.
    /// </summary>
    public static string GetAbsoluteUrl(string action, string controller, UrlHelper urlHelper, object routeValues = null)
    {
        var uri = urlHelper.Action(action, controller, routeValues, "http");

        return uri;
    }
}
Brian MacKay
quelle
-5

Sie haben einige Möglichkeiten:

  • Speichern Sie den Wert von HttpContext.Request.Url in einer statischen oder Mitgliedsvariablen und übergeben Sie damit den vollständig qualifizierten Pfad.
  • Speichern Sie die App-Domain in einer App-Einstellung in der web.config.
  • Codieren Sie den Wert fest.
Keith
quelle