In MVC 5 hatte ich die folgenden Erweiterungsmethoden, um absolute URLs anstelle relativer URLs zu generieren:
public static class UrlHelperExtensions
{
public static string AbsoluteAction(
this UrlHelper url,
string actionName,
string controllerName,
object routeValues = null)
{
string scheme = url.RequestContext.HttpContext.Request.Url.Scheme;
return url.Action(actionName, controllerName, routeValues, scheme);
}
public static string AbsoluteContent(
this UrlHelper url,
string contentPath)
{
return new Uri(url.RequestContext.HttpContext.Request.Url, url.Content(contentPath)).ToString();
}
public static string AbsoluteRouteUrl(
this UrlHelper url,
string routeName,
object routeValues = null)
{
string scheme = url.RequestContext.HttpContext.Request.Url.Scheme;
return url.RouteUrl(routeName, routeValues, scheme);
}
}
Was wäre das Äquivalent in ASP.NET Core?
UrlHelper.RequestContext
existiert nicht mehr.- Sie können das nicht erreichen,
HttpContext
da es keine statischeHttpContext.Current
Eigenschaft mehr gibt .
Soweit ich sehen kann, müssten Sie jetzt auch die HttpContext
oder HttpRequest
Objekte übergeben. Habe ich recht? Gibt es eine Möglichkeit, die aktuelle Anfrage zu erhalten?
Bin ich überhaupt auf dem richtigen Weg, sollte die Domain jetzt eine Umgebungsvariable sein, die einfach an die relative URL angehängt wird? Wäre dies ein besserer Ansatz?
c#
asp.net-core
Muhammad Rehan Saeed
quelle
quelle
http://example.com/controller/action
Antworten:
Nach RC2 und 1.0 müssen Sie
IHttpContextAccessor
Ihrer Erweiterungsklasse keine Erweiterungsklasse mehr hinzufügen. Es ist sofort in derIUrlHelper
durch dieurlhelper.ActionContext.HttpContext.Request
. Sie würden dann eine Erweiterungsklasse erstellen, die der gleichen Idee folgt, jedoch einfacher ist, da keine Injektion erforderlich ist.public static string AbsoluteAction( this IUrlHelper url, string actionName, string controllerName, object routeValues = null) { string scheme = url.ActionContext.HttpContext.Request.Scheme; return url.Action(actionName, controllerName, routeValues, scheme); }
Lassen Sie die Details darüber, wie man es baut, und injizieren Sie den Zugang, falls sie für jemanden nützlich sind. Möglicherweise interessiert Sie auch nur die absolute URL der aktuellen Anfrage. In diesem Fall sehen Sie sich das Ende der Antwort an.
Sie können Ihre Erweiterungsklasse ändern, um die
IHttpContextAccessor
Schnittstelle zum Abrufen der zu verwendenHttpContext
. Sobald Sie den Kontext haben, dann können Sie die bekommenHttpRequest
Instanz ausHttpContext.Request
und verwenden seine EigenschaftenScheme
,Host
,Protocol
usw. , wie in:string scheme = HttpContextAccessor.HttpContext.Request.Scheme;
Beispielsweise könnte es erforderlich sein, dass Ihre Klasse mit einem HttpContextAccessor konfiguriert wird:
public static class UrlHelperExtensions { private static IHttpContextAccessor HttpContextAccessor; public static void Configure(IHttpContextAccessor httpContextAccessor) { HttpContextAccessor = httpContextAccessor; } public static string AbsoluteAction( this IUrlHelper url, string actionName, string controllerName, object routeValues = null) { string scheme = HttpContextAccessor.HttpContext.Request.Scheme; return url.Action(actionName, controllerName, routeValues, scheme); } .... }
Was können Sie in Ihrer
Startup
Klasse tun (Startup.cs-Datei):public void Configure(IApplicationBuilder app) { ... var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>(); UrlHelperExtensions.Configure(httpContextAccessor); ... }
Sie könnten wahrscheinlich verschiedene Möglichkeiten finden, um die
IHttpContextAccessor
in Ihrer Erweiterungsklasse zu erhalten, aber wenn Sie Ihre Methoden am Ende als Erweiterungsmethoden beibehalten möchten, müssen Sie dieIHttpContextAccessor
in Ihre statische Klasse einfügen. (Andernfalls benötigen Sie dasIHttpContext
als Argument bei jedem Aufruf)Nur das absoluteUri der aktuellen Anfrage erhalten
Wenn Sie nur die absolute URL der aktuellen Anforderung abrufen möchten, können Sie die Erweiterungsmethoden
GetDisplayUrl
oderGetEncodedUrl
dieUriHelper
Klasse verwenden. (Was sich vom Ur L Helper unterscheidet)Um sie zu verwenden:
Microsoft.AspNet.Http.Extensions
.HttpContext
Instanz. Es ist bereits in einigen Klassen verfügbar (z. B. in Rasiereransichten), in anderen müssen Sie möglicherweise eine injizieren,IHttpContextAccessor
wie oben erläutert.this.Context.Request.GetDisplayUrl()
Eine Alternative zu diesen Methoden wäre das manuelle Erstellen des absoluten Uri mithilfe der Werte im
HttpContext.Request
Objekt (ähnlich wie beim RequireHttpsAttribute ):var absoluteUri = string.Concat( request.Scheme, "://", request.Host.ToUriComponent(), request.PathBase.ToUriComponent(), request.Path.ToUriComponent(), request.QueryString.ToUriComponent());
quelle
UriHelper
Link ist tot.@using Microsoft.AspNet.Http.Extensions
der Ansicht Index.cshtml hinzugefügt und konnte diese Erweiterungen wie in@Context.Request.GetDisplayUrl()
Ab ASP.NET Core 1.0
/// <summary> /// <see cref="IUrlHelper"/> extension methods. /// </summary> public static class UrlHelperExtensions { /// <summary> /// Generates a fully qualified URL to an action method by using the specified action name, controller name and /// route values. /// </summary> /// <param name="url">The URL helper.</param> /// <param name="actionName">The name of the action method.</param> /// <param name="controllerName">The name of the controller.</param> /// <param name="routeValues">The route values.</param> /// <returns>The absolute URL.</returns> public static string AbsoluteAction( this IUrlHelper url, string actionName, string controllerName, object routeValues = null) { return url.Action(actionName, controllerName, routeValues, url.ActionContext.HttpContext.Request.Scheme); } /// <summary> /// Generates a fully qualified URL to the specified content by using the specified content path. Converts a /// virtual (relative) path to an application absolute path. /// </summary> /// <param name="url">The URL helper.</param> /// <param name="contentPath">The content path.</param> /// <returns>The absolute URL.</returns> public static string AbsoluteContent( this IUrlHelper url, string contentPath) { HttpRequest request = url.ActionContext.HttpContext.Request; return new Uri(new Uri(request.Scheme + "://" + request.Host.Value), url.Content(contentPath)).ToString(); } /// <summary> /// Generates a fully qualified URL to the specified route by using the route name and route values. /// </summary> /// <param name="url">The URL helper.</param> /// <param name="routeName">Name of the route.</param> /// <param name="routeValues">The route values.</param> /// <returns>The absolute URL.</returns> public static string AbsoluteRouteUrl( this IUrlHelper url, string routeName, object routeValues = null) { return url.RouteUrl(routeName, routeValues, url.ActionContext.HttpContext.Request.Scheme); } }
Bonus-Tipp
Sie können eine nicht direkt
IUrlHelper
im DI-Container registrieren .IUrlHelper
Zum Auflösen einer Instanz von müssen Sie dasIUrlHelperFactory
und verwendenIActionContextAccessor
. Als Verknüpfung können Sie jedoch Folgendes tun:ASP.NET Core Backlog
UPDATE : Dadurch wird ASP.NET Core 5 nicht erstellt
Es gibt Hinweise darauf, dass Sie
LinkGenerator
absolute URLs erstellen können, ohne eine angeben zu müssenHttpContext
(Dies war der größte NachteilLinkGenerator
und warumIUrlHelper
die Einrichtung mit der folgenden Lösung komplexer war, obwohl sie einfacher zu verwenden war). Siehe "Vereinfachen Sie die Konfiguration." ein Host / Schema für absolute URLs mit LinkGenerator " .quelle
string url = string.Concat(this.Request.Scheme, "://", this.Request.Host, this.Request.Path, this.Request.QueryString);
Sie müssen hierfür keine Erweiterungsmethode erstellen
@Url.Action("Action", "Controller", values: null);
Action
- Name der AktionController
- Name des Controllersvalues
- Objekt mit Routenwerten: auch bekannt als GET-ParameterEs gibt auch viele andere Überladungen, mit denen
Url.Action
Sie Links generieren können.quelle
this.Context.Request.Scheme
. Erhält das nur die Protokoll- und Domänenteile der URL?this.Context.Request.Schema
Gibt das Protokoll zurück, das für die Anforderung verwendet wurde. Es wirdhttp
oder seinhttps
. Hier sind die Dokumente, aber sie erklären nicht wirklich, was Schema bedeutet.Wenn Sie einfach einen Uri für eine Methode mit einer Routenanmerkung benötigen, hat das Folgende für mich funktioniert.
Schritte
Relative URL abrufen
Wenn Sie den Routennamen der Zielaktion notieren, rufen Sie die relative URL mithilfe der URL- Eigenschaft des Controllers wie folgt ab:
var routeUrl = Url.RouteUrl("*Route Name Here*", new { *Route parameters here* });
Erstellen Sie eine absolute URL
var absUrl = string.Format("{0}://{1}{2}", Request.Scheme, Request.Host, routeUrl);
Erstellen Sie einen neuen Uri
var uri = new Uri(absUrl, UriKind.Absolute)
Beispiel
[Produces("application/json")] [Route("api/Children")] public class ChildrenController : Controller { private readonly ApplicationDbContext _context; public ChildrenController(ApplicationDbContext context) { _context = context; } // GET: api/Children [HttpGet] public IEnumerable<Child> GetChild() { return _context.Child; } [HttpGet("uris")] public IEnumerable<Uri> GetChildUris() { return from c in _context.Child select new Uri( $"{Request.Scheme}://{Request.Host}{Url.RouteUrl("GetChildRoute", new { id = c.ChildId })}", UriKind.Absolute); } // GET: api/Children/5 [HttpGet("{id}", Name = "GetChildRoute")] public IActionResult GetChild([FromRoute] int id) { if (!ModelState.IsValid) { return HttpBadRequest(ModelState); } Child child = _context.Child.Single(m => m.ChildId == id); if (child == null) { return HttpNotFound(); } return Ok(child); } }
quelle
Dies ist eine Variation der Antwort von Muhammad Rehan Saeed , wobei die Klasse parasitär an die vorhandene gleichnamige .net-Kern-MVC-Klasse gebunden wird, sodass alles einfach funktioniert.
namespace Microsoft.AspNetCore.Mvc { /// <summary> /// <see cref="IUrlHelper"/> extension methods. /// </summary> public static partial class UrlHelperExtensions { /// <summary> /// Generates a fully qualified URL to an action method by using the specified action name, controller name and /// route values. /// </summary> /// <param name="url">The URL helper.</param> /// <param name="actionName">The name of the action method.</param> /// <param name="controllerName">The name of the controller.</param> /// <param name="routeValues">The route values.</param> /// <returns>The absolute URL.</returns> public static string AbsoluteAction( this IUrlHelper url, string actionName, string controllerName, object routeValues = null) { return url.Action(actionName, controllerName, routeValues, url.ActionContext.HttpContext.Request.Scheme); } /// <summary> /// Generates a fully qualified URL to the specified content by using the specified content path. Converts a /// virtual (relative) path to an application absolute path. /// </summary> /// <param name="url">The URL helper.</param> /// <param name="contentPath">The content path.</param> /// <returns>The absolute URL.</returns> public static string AbsoluteContent( this IUrlHelper url, string contentPath) { HttpRequest request = url.ActionContext.HttpContext.Request; return new Uri(new Uri(request.Scheme + "://" + request.Host.Value), url.Content(contentPath)).ToString(); } /// <summary> /// Generates a fully qualified URL to the specified route by using the route name and route values. /// </summary> /// <param name="url">The URL helper.</param> /// <param name="routeName">Name of the route.</param> /// <param name="routeValues">The route values.</param> /// <returns>The absolute URL.</returns> public static string AbsoluteRouteUrl( this IUrlHelper url, string routeName, object routeValues = null) { return url.RouteUrl(routeName, routeValues, url.ActionContext.HttpContext.Request.Scheme); } } }
quelle
In einem neuen Projekt MVC ASP.Net 5 in einer Controller - Aktion können Sie noch tun ,
this.Context
undthis.Context.Request
es sieht aus wie auf dem Antrag gibt es nicht mehr eine Eigenschaft Url , aber die untergeordneten Eigenschaften (Schema, Host, etc.) sind alle auf dem Request - Objekt direkt.public IActionResult About() { ViewBag.Message = "Your application description page."; var schema = this.Context.Request.Scheme; return View(); }
Eher oder nicht möchten Sie dies verwenden. Kontext oder Injizieren der Eigenschaft ist eine weitere Konversation. Abhängigkeitsinjektion in ASP.NET vNext
quelle
Wenn Sie nur einen relativen Pfad mit optionalen Parametern konvertieren möchten, habe ich eine Erweiterungsmethode für IHttpContextAccessor erstellt
public static string AbsoluteUrl(this IHttpContextAccessor httpContextAccessor, string relativeUrl, object parameters = null) { var request = httpContextAccessor.HttpContext.Request; var url = new Uri(new Uri($"{request.Scheme}://{request.Host.Value}"), relativeUrl).ToString(); if (parameters != null) { url = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(url, ToDictionary(parameters)); } return url; } private static Dictionary<string, string> ToDictionary(object obj) { var json = JsonConvert.SerializeObject(obj); return JsonConvert.DeserializeObject<Dictionary<string, string>>(json); }
Sie können die Methode dann von Ihrem Dienst / Ihrer Ansicht aus mit dem injizierten IHttpContextAccessor aufrufen
var callbackUrl = _httpContextAccessor.AbsoluteUrl("/Identity/Account/ConfirmEmail", new { userId = applicationUser.Id, code });
quelle
Ich habe gerade festgestellt, dass Sie dies mit diesem Aufruf tun können:
Url.Action(new UrlActionContext { Protocol = Request.Scheme, Host = Request.Host.Value, Action = "Action" })
Dadurch werden das Schema, der Host, der Port und alles beibehalten.
quelle
Sie können die URL wie folgt erhalten:
Request.Headers["Referer"]
Erläuterung
Das
Request.UrlReferer
wird einenSystem.UriFormatException
auslösen, wenn der HTTP-Header des Referers fehlerhaft ist (was passieren kann, da er normalerweise nicht unter Ihrer Kontrolle steht).Wie für die Verwendung
Request.ServerVariables
, pro MSDN :Request.Headers-Eigenschaft
Ruft eine Sammlung von HTTP-Headern ab.
Ich glaube , ich verstehe nicht , warum Sie würden die lieber
Request.ServerVariables
überRequest.Headers
, daRequest.ServerVariables
alle Umgebungsvariablen enthält sowie die Header, wo Request.Headers ist eine viel kürzere Liste , dass nur die Header enthält.Die beste Lösung besteht also darin, die
Request.Headers
Sammlung zu verwenden, um den Wert direkt zu lesen. Beachten Sie jedoch die Warnungen von Microsoft bezüglich der HTML-Codierung des Werts, wenn Sie ihn in einem Formular anzeigen möchten.quelle