| File: Routing\UrlHelper.cs | Web Access |
| Project: src\aspnetcore\src\Mvc\Mvc.Core\src\Microsoft.AspNetCore.Mvc.Core.csproj (Microsoft.AspNetCore.Mvc.Core) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; namespace Microsoft.AspNetCore.Mvc.Routing; /// <summary> /// An implementation of <see cref="IUrlHelper"/> that contains methods to /// build URLs for ASP.NET MVC within an application. /// </summary> public class UrlHelper : UrlHelperBase { /// <summary> /// Initializes a new instance of the <see cref="UrlHelper"/> class using the specified /// <paramref name="actionContext"/>. /// </summary> /// <param name="actionContext">The <see cref="Mvc.ActionContext"/> for the current request.</param> public UrlHelper(ActionContext actionContext) : base(actionContext) { } /// <summary> /// Gets the <see cref="Http.HttpContext"/> associated with the current request. /// </summary> protected HttpContext HttpContext => ActionContext.HttpContext; /// <summary> /// Gets the top-level <see cref="IRouter"/> associated with the current request. Generally an /// <see cref="IRouteCollection"/> implementation. /// </summary> protected IRouter Router { get { var routers = ActionContext.RouteData.Routers; if (routers.Count == 0) { throw new InvalidOperationException("Could not find an IRouter associated with the ActionContext. " + "If your application is using endpoint routing then you can get a IUrlHelperFactory with " + "dependency injection and use it to create a UrlHelper, or use Microsoft.AspNetCore.Routing.LinkGenerator."); } return routers[0]; } } /// <inheritdoc /> public override string? Action(UrlActionContext actionContext) { ArgumentNullException.ThrowIfNull(actionContext); var valuesDictionary = GetValuesDictionary(actionContext.Values); NormalizeRouteValuesForAction(actionContext.Action, actionContext.Controller, valuesDictionary, AmbientValues); var virtualPathData = GetVirtualPathData(routeName: null, values: valuesDictionary); return GenerateUrl(actionContext.Protocol, actionContext.Host, virtualPathData, actionContext.Fragment); } /// <inheritdoc /> public override string? RouteUrl(UrlRouteContext routeContext) { ArgumentNullException.ThrowIfNull(routeContext); var valuesDictionary = routeContext.Values as RouteValueDictionary ?? GetValuesDictionary(routeContext.Values); var virtualPathData = GetVirtualPathData(routeContext.RouteName, valuesDictionary); return GenerateUrl(routeContext.Protocol, routeContext.Host, virtualPathData, routeContext.Fragment); } /// <summary> /// Gets the <see cref="VirtualPathData"/> for the specified <paramref name="routeName"/> and route /// <paramref name="values"/>. /// </summary> /// <param name="routeName">The name of the route that is used to generate the <see cref="VirtualPathData"/>. /// </param> /// <param name="values"> /// The <see cref="RouteValueDictionary"/>. The <see cref="Router"/> uses these values, in combination with /// <see cref="UrlHelperBase.AmbientValues"/>, to generate the URL. /// </param> /// <returns>The <see cref="VirtualPathData"/>.</returns> protected virtual VirtualPathData? GetVirtualPathData(string? routeName, RouteValueDictionary values) { var context = new VirtualPathContext(HttpContext, AmbientValues, values, routeName); return Router.GetVirtualPath(context); } /// <summary> /// Generates the URL using the specified components. /// </summary> /// <param name="protocol">The protocol for the URL, such as "http" or "https".</param> /// <param name="host">The host name for the URL.</param> /// <param name="pathData">The <see cref="VirtualPathData"/>.</param> /// <param name="fragment">The fragment for the URL.</param> /// <returns>The generated URL.</returns> protected virtual string? GenerateUrl(string? protocol, string? host, VirtualPathData? pathData, string? fragment) { return GenerateUrl(protocol, host, pathData?.VirtualPath, fragment); } }