using System; using System.Collections.Generic; using System.Dynamic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Hosting; using Umbraco.Cms.Core.Web.Mvc; using Umbraco.Cms.Web.Common.Controllers; namespace Umbraco.Extensions { public static class LinkGeneratorExtensions { /// /// Return the back office url if the back office is installed /// public static string GetBackOfficeUrl(this LinkGenerator linkGenerator, IHostingEnvironment hostingEnvironment) { Type backOfficeControllerType; try { backOfficeControllerType = Assembly.Load("Umbraco.Web.BackOffice")?.GetType("Umbraco.Web.BackOffice.Controllers.BackOfficeController"); if (backOfficeControllerType == null) { return "/"; // this would indicate that the installer is installed without the back office } } catch { return hostingEnvironment.ApplicationVirtualPath; // this would indicate that the installer is installed without the back office } return linkGenerator.GetPathByAction("Default", ControllerExtensions.GetControllerName(backOfficeControllerType), values: new { area = Cms.Core.Constants.Web.Mvc.BackOfficeApiArea }); } /// /// Return the Url for a Web Api service /// /// The public static string GetUmbracoApiService(this LinkGenerator linkGenerator, string actionName, object id = null) where T : UmbracoApiControllerBase => linkGenerator.GetUmbracoControllerUrl( actionName, typeof(T), new Dictionary() { ["id"] = id }); public static string GetUmbracoApiService(this LinkGenerator linkGenerator, string actionName, IDictionary values) where T : UmbracoApiControllerBase => linkGenerator.GetUmbracoControllerUrl(actionName, typeof(T), values); public static string GetUmbracoApiServiceBaseUrl(this LinkGenerator linkGenerator, Expression> methodSelector) where T : UmbracoApiControllerBase { var method = ExpressionHelper.GetMethodInfo(methodSelector); if (method == null) { throw new MissingMethodException("Could not find the method " + methodSelector + " on type " + typeof(T) + " or the result "); } return linkGenerator.GetUmbracoApiService(method.Name).TrimEnd(method.Name); } /// /// Return the Url for an Umbraco controller /// public static string GetUmbracoControllerUrl(this LinkGenerator linkGenerator, string actionName, string controllerName, string area, IDictionary dict = null) { if (actionName == null) { throw new ArgumentNullException(nameof(actionName)); } if (string.IsNullOrWhiteSpace(actionName)) { throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(actionName)); } if (controllerName == null) { throw new ArgumentNullException(nameof(controllerName)); } if (string.IsNullOrWhiteSpace(controllerName)) { throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(controllerName)); } if (dict is null) { dict = new Dictionary(); } if (!area.IsNullOrWhiteSpace()) { dict["area"] = area; } IDictionary values = dict.Aggregate( new ExpandoObject() as IDictionary, (a, p) => { a.Add(p.Key, p.Value); return a; }); return linkGenerator.GetPathByAction(actionName, controllerName, values); } /// /// Return the Url for an Umbraco controller /// public static string GetUmbracoControllerUrl(this LinkGenerator linkGenerator, string actionName, Type controllerType, IDictionary values = null) { if (actionName == null) { throw new ArgumentNullException(nameof(actionName)); } if (string.IsNullOrWhiteSpace(actionName)) { throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(actionName)); } if (controllerType == null) { throw new ArgumentNullException(nameof(controllerType)); } var area = string.Empty; if (!typeof(ControllerBase).IsAssignableFrom(controllerType)) { throw new InvalidOperationException($"The controller {controllerType} is of type {typeof(ControllerBase)}"); } PluginControllerMetadata metaData = PluginController.GetMetadata(controllerType); if (metaData.AreaName.IsNullOrWhiteSpace() == false) { // set the area to the plugin area area = metaData.AreaName; } return linkGenerator.GetUmbracoControllerUrl(actionName, ControllerExtensions.GetControllerName(controllerType), area, values); } public static string GetUmbracoApiService(this LinkGenerator linkGenerator, Expression> methodSelector) where T : UmbracoApiController { var method = ExpressionHelper.GetMethodInfo(methodSelector); var methodParams = ExpressionHelper.GetMethodParams(methodSelector); if (method == null) { throw new MissingMethodException( $"Could not find the method {methodSelector} on type {typeof(T)} or the result "); } if (methodParams.Any() == false) { return linkGenerator.GetUmbracoApiService(method.Name); } return linkGenerator.GetUmbracoApiService(method.Name, methodParams); } } }