/// <summary> /// Generates a URL based on the current Umbraco URL with a custom query string that will route to the specified SurfaceController /// </summary> /// <param name="url"></param> /// <param name="action"></param> /// <param name="surfaceType"></param> /// <param name="additionalRouteVals"></param> /// <returns></returns> public static string SurfaceAction(this UrlHelper url, string action, Type surfaceType, object additionalRouteVals) { if (string.IsNullOrEmpty(action)) { throw new ArgumentNullOrEmptyException(nameof(action)); } if (surfaceType == null) { throw new ArgumentNullException(nameof(surfaceType)); } var area = ""; var surfaceController = Current.SurfaceControllerTypes.SingleOrDefault(x => x == surfaceType); if (surfaceController == null) { throw new InvalidOperationException("Could not find the surface controller of type " + surfaceType.FullName); } var metaData = PluginController.GetMetadata(surfaceController); if (metaData.AreaName.IsNullOrWhiteSpace() == false) { //set the area to the plugin area area = metaData.AreaName; } var encryptedRoute = CreateEncryptedRouteString(metaData.ControllerName, action, area, additionalRouteVals); var result = Current.UmbracoContext.OriginalRequestUrl.AbsolutePath.EnsureEndsWith('?') + "ufprt=" + encryptedRoute; return(result); }
/// <summary> /// Return the Url for a Web Api service /// </summary> /// <param name="url"></param> /// <param name="actionName"></param> /// <param name="apiControllerType"></param> /// <param name="id"></param> /// <returns></returns> public static string GetUmbracoApiService(this UrlHelper url, string actionName, Type apiControllerType, object id = 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 (apiControllerType == null) { throw new ArgumentNullException(nameof(apiControllerType)); } var area = ""; var apiController = Current.UmbracoApiControllerTypes .SingleOrDefault(x => x == apiControllerType); if (apiController == null) { throw new InvalidOperationException("Could not find the umbraco api controller of type " + apiControllerType.FullName); } var metaData = PluginController.GetMetadata(apiController); if (metaData.AreaName.IsNullOrWhiteSpace() == false) { //set the area to the plugin area area = metaData.AreaName; } return(url.GetUmbracoApiService(actionName, ControllerExtensions.GetControllerName(apiControllerType), area, id)); }
/// <summary> /// Returns the result of a child action of a SurfaceController /// </summary> /// <typeparam name="T"></typeparam> /// <param name="htmlHelper"></param> /// <param name="actionName"></param> /// <param name="surfaceType"></param> /// <returns></returns> public static IHtmlString Action(this HtmlHelper htmlHelper, string actionName, Type surfaceType) { Mandate.ParameterNotNull(surfaceType, "surfaceType"); Mandate.ParameterNotNullOrEmpty(actionName, "actionName"); var routeVals = new RouteValueDictionary(new { area = "" }); var surfaceController = SurfaceControllerResolver.Current.RegisteredSurfaceControllers .SingleOrDefault(x => x == surfaceType); if (surfaceController == null) { throw new InvalidOperationException("Could not find the surface controller of type " + surfaceType.FullName); } var metaData = PluginController.GetMetadata(surfaceController); if (!metaData.AreaName.IsNullOrWhiteSpace()) { //set the area to the plugin area if (routeVals.ContainsKey("area")) { routeVals["area"] = metaData.AreaName; } else { routeVals.Add("area", metaData.AreaName); } } return(htmlHelper.Action(actionName, metaData.ControllerName, routeVals)); }
private void RoutePluginControllers() { var umbracoPath = GlobalSettings.UmbracoMvcArea; //we need to find the plugin controllers and route them var pluginControllers = SurfaceControllerResolver.Current.RegisteredSurfaceControllers.Concat( UmbracoApiControllerResolver.Current.RegisteredUmbracoApiControllers).ToArray(); //local controllers do not contain the attribute var localControllers = pluginControllers.Where(x => PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace()); foreach (var s in localControllers) { if (TypeHelper.IsTypeAssignableFrom<SurfaceController>(s)) { RouteLocalSurfaceController(s, umbracoPath); } else if (TypeHelper.IsTypeAssignableFrom<UmbracoApiController>(s)) { RouteLocalApiController(s, umbracoPath); } } //need to get the plugin controllers that are unique to each area (group by) var pluginSurfaceControlleres = pluginControllers.Where(x => !PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace()); var groupedAreas = pluginSurfaceControlleres.GroupBy(controller => PluginController.GetMetadata(controller).AreaName); //loop through each area defined amongst the controllers foreach (var g in groupedAreas) { //create an area for the controllers (this will throw an exception if all controllers are not in the same area) var pluginControllerArea = new PluginControllerArea(g.Select(PluginController.GetMetadata)); //register it RouteTable.Routes.RegisterArea(pluginControllerArea); } }
/// <summary> /// Return the Url for a Web Api service /// </summary> /// <param name="url"></param> /// <param name="actionName"></param> /// <param name="apiControllerType"></param> /// <param name="routeVals"></param> /// <returns></returns> public static string GetUmbracoApiService(this UrlHelper url, string actionName, Type apiControllerType, RouteValueDictionary routeVals = null) { if (string.IsNullOrEmpty(actionName)) { throw new ArgumentNullOrEmptyException(nameof(actionName)); } if (apiControllerType == null) { throw new ArgumentNullException(nameof(apiControllerType)); } var area = ""; var apiController = Current.UmbracoApiControllerTypes .SingleOrDefault(x => x == apiControllerType); if (apiController == null) { throw new InvalidOperationException("Could not find the umbraco api controller of type " + apiControllerType.FullName); } var metaData = PluginController.GetMetadata(apiController); if (!metaData.AreaName.IsNullOrWhiteSpace()) { //set the area to the plugin area area = metaData.AreaName; } return(url.GetUmbracoApiService(actionName, ControllerExtensions.GetControllerName(apiControllerType), area, routeVals)); }
/// <summary> /// Auto-routes all back office api controllers /// </summary> private void AutoRouteBackOfficeApiControllers(IEndpointRouteBuilder endpoints) { // TODO: We could investigate dynamically routing plugin controllers so we don't have to eagerly type scan for them, // it would probably work well, see https://www.strathweb.com/2019/08/dynamic-controller-routing-in-asp-net-core-3-0/ // will probably be what we use for front-end routing too. BTW the orig article about migrating from IRouter to endpoint // routing for things like a CMS is here https://github.com/dotnet/aspnetcore/issues/4221 foreach (Type controller in _apiControllers) { PluginControllerMetadata meta = PluginController.GetMetadata(controller); // exclude front-end api controllers if (!meta.IsBackOffice) { continue; } endpoints.MapUmbracoApiRoute( meta.ControllerType, _umbracoPathSegment, meta.AreaName, meta.IsBackOffice, string.Empty); // no default action (this is what we had before) } }
/// <summary> /// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin /// </summary> /// <param name="html"></param> /// <param name="action"></param> /// <param name="surfaceType">The surface controller to route to</param> /// <param name="additionalRouteVals"></param> /// <param name="htmlAttributes"></param> /// <returns></returns> public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, Type surfaceType, object additionalRouteVals, IDictionary <string, object> htmlAttributes) { Mandate.ParameterNotNullOrEmpty(action, "action"); Mandate.ParameterNotNull(surfaceType, "surfaceType"); var area = ""; var surfaceController = SurfaceControllerResolver.Current.RegisteredSurfaceControllers .SingleOrDefault(x => x == surfaceType); if (surfaceController == null) { throw new InvalidOperationException("Could not find the surface controller of type " + surfaceType.FullName); } var metaData = PluginController.GetMetadata(surfaceController); if (!metaData.AreaName.IsNullOrWhiteSpace()) { //set the area to the plugin area area = metaData.AreaName; } return(html.BeginUmbracoForm(action, metaData.ControllerName, area, additionalRouteVals, htmlAttributes)); }
/// <summary> /// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin /// </summary> /// <param name="html"></param> /// <param name="action"></param> /// <param name="surfaceType">The surface controller to route to</param> /// <param name="additionalRouteVals"></param> /// <param name="htmlAttributes"></param> /// <param name="method"></param> /// <returns></returns> public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, Type surfaceType, object additionalRouteVals, IDictionary <string, object> htmlAttributes, FormMethod method) { if (string.IsNullOrWhiteSpace(action)) { throw new ArgumentNullOrEmptyException(nameof(action)); } if (surfaceType == null) { throw new ArgumentNullException(nameof(surfaceType)); } var area = ""; var surfaceController = Current.SurfaceControllerTypes.SingleOrDefault(x => x == surfaceType); if (surfaceController == null) { throw new InvalidOperationException("Could not find the surface controller of type " + surfaceType.FullName); } var metaData = PluginController.GetMetadata(surfaceController); if (metaData.AreaName.IsNullOrWhiteSpace() == false) { //set the area to the plugin area area = metaData.AreaName; } return(html.BeginUmbracoForm(action, metaData.ControllerName, area, additionalRouteVals, htmlAttributes, method)); }
/// <summary> /// Return the Url for an Umbraco controller /// </summary> public static string GetUmbracoControllerUrl(this LinkGenerator linkGenerator, string actionName, Type controllerType, IDictionary <string, object> 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 void Ensure_Same_Area3() { Assert.Throws <InvalidOperationException>(() => new PluginControllerArea(new PluginControllerMetadata[] { PluginController.GetMetadata(typeof(Plugin1Controller)), PluginController.GetMetadata(typeof(Plugin2Controller)), PluginController.GetMetadata(typeof(Plugin4Controller)) //no area assigned })); }
public void Ensure_Same_Area1() { Assert.Throws <InvalidOperationException>(() => new PluginControllerArea(new PluginControllerMetadata[] { PluginController.GetMetadata(typeof(Controller1)), PluginController.GetMetadata(typeof(Controller2)), PluginController.GetMetadata(typeof(Controller3)) //not same area })); }
public void Ensure_Same_Area2() { var area = new PluginControllerArea(new PluginControllerMetadata[] { PluginController.GetMetadata(typeof(Plugin1Controller)), PluginController.GetMetadata(typeof(Plugin2Controller)) }); Assert.Pass(); }
public void Ensure_Same_Area2() { var area = new PluginControllerArea(TestObjects.GetGlobalSettings(), new PluginControllerMetadata[] { PluginController.GetMetadata(typeof(Plugin1Controller)), PluginController.GetMetadata(typeof(Plugin2Controller)) }); Assert.Pass(); }
public void Ensure_Same_Area1() { Assert.Throws <InvalidOperationException>(() => new PluginControllerArea(TestObjects.GetGlobalSettings(), new PluginControllerMetadata[] { PluginController.GetMetadata(typeof(Plugin1Controller)), PluginController.GetMetadata(typeof(Plugin2Controller)), PluginController.GetMetadata(typeof(Plugin3Controller)) //not same area })); }
/// <summary> /// Helper method to create a new form to execute in the Umbraco request pipeline to a surface controller plugin /// </summary> public static MvcForm BeginUmbracoForm( this IHtmlHelper html, string action, Type surfaceType, object?additionalRouteVals, IDictionary <string, object?> htmlAttributes, FormMethod method) { if (action == null) { throw new ArgumentNullException(nameof(action)); } if (string.IsNullOrWhiteSpace(action)) { throw new ArgumentException( "Value can't be empty or consist only of white-space characters.", nameof(action)); } if (surfaceType == null) { throw new ArgumentNullException(nameof(surfaceType)); } SurfaceControllerTypeCollection surfaceControllerTypeCollection = GetRequiredService <SurfaceControllerTypeCollection>(html); Type?surfaceController = surfaceControllerTypeCollection.SingleOrDefault(x => x == surfaceType); if (surfaceController == null) { throw new InvalidOperationException("Could not find the surface controller of type " + surfaceType.FullName); } PluginControllerMetadata metaData = PluginController.GetMetadata(surfaceController); var area = string.Empty; if (metaData.AreaName.IsNullOrWhiteSpace() == false) { // Set the area to the plugin area area = metaData.AreaName; } return(html.BeginUmbracoForm( action, metaData.ControllerName, area !, additionalRouteVals, htmlAttributes, method)); }
/// <summary> /// Creates the routes /// </summary> protected internal void CreateRoutes() { var umbracoPath = GlobalSettings.UmbracoMvcArea; //Create the front-end route var defaultRoute = RouteTable.Routes.MapRoute( "Umbraco_default", "Umbraco/RenderMvc/{action}/{id}", new { controller = "RenderMvc", action = "Index", id = UrlParameter.Optional } ); defaultRoute.RouteHandler = new RenderRouteHandler(ControllerBuilder.Current.GetControllerFactory()); //Create the install routes var installPackageRoute = RouteTable.Routes.MapRoute( "Umbraco_install_packages", "Install/PackageInstaller/{action}/{id}", new { controller = "InstallPackage", action = "Index", id = UrlParameter.Optional } ); installPackageRoute.DataTokens.Add("area", umbracoPath); //we need to find the surface controllers and route them var surfaceControllers = SurfaceControllerResolver.Current.RegisteredSurfaceControllers.ToArray(); //local surface controllers do not contain the attribute var localSurfaceControlleres = surfaceControllers.Where(x => PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace()); foreach (var s in localSurfaceControlleres) { var meta = PluginController.GetMetadata(s); var route = RouteTable.Routes.MapRoute( string.Format("umbraco-{0}-{1}", "surface", meta.ControllerName), umbracoPath + "/Surface/" + meta.ControllerName + "/{action}/{id}", //url to match new { controller = meta.ControllerName, action = "Index", id = UrlParameter.Optional }, new[] { meta.ControllerNamespace }); //only match this namespace route.DataTokens.Add("umbraco", "surface"); //ensure the umbraco token is set } //need to get the plugin controllers that are unique to each area (group by) //TODO: One day when we have more plugin controllers, we will need to do a group by on ALL of them to pass into the ctor of PluginControllerArea var pluginSurfaceControlleres = surfaceControllers.Where(x => !PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace()); var groupedAreas = pluginSurfaceControlleres.GroupBy(controller => PluginController.GetMetadata(controller).AreaName); //loop through each area defined amongst the controllers foreach (var g in groupedAreas) { //create an area for the controllers (this will throw an exception if all controllers are not in the same area) var pluginControllerArea = new PluginControllerArea(g.Select(PluginController.GetMetadata)); //register it RouteTable.Routes.RegisterArea(pluginControllerArea); } }
private void RouteLocalSurfaceController(Type controller, string umbracoPath) { var meta = PluginController.GetMetadata(controller); var route = RouteTable.Routes.MapRoute( string.Format("umbraco-{0}-{1}", "surface", meta.ControllerName), umbracoPath + "/Surface/" + meta.ControllerName + "/{action}/{id}",//url to match new { controller = meta.ControllerName, action = "Index", id = UrlParameter.Optional }, new[] { meta.ControllerNamespace }); //look in this namespace to create the controller route.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, "surface"); //ensure the umbraco token is set route.DataTokens.Add("UseNamespaceFallback", false); //Don't look anywhere else except this namespace! //make it use our custom/special SurfaceMvcHandler route.RouteHandler = new SurfaceRouteHandler(); }
/// <summary> /// Auto-routes all front-end surface controllers /// </summary> private void AutoRouteSurfaceControllers(IEndpointRouteBuilder endpoints) { foreach (Type controller in _surfaceControllerTypeCollection) { // exclude front-end api controllers PluginControllerMetadata meta = PluginController.GetMetadata(controller); endpoints.MapUmbracoSurfaceRoute( meta.ControllerType, _umbracoPathSegment, meta.AreaName); } }
/// <summary> /// Returns the result of a child action of a SurfaceController /// </summary> public static IHtmlContent ActionLink(this IHtmlHelper htmlHelper, string actionName, Type surfaceType) { 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 (surfaceType == null) { throw new ArgumentNullException(nameof(surfaceType)); } SurfaceControllerTypeCollection surfaceControllerTypeCollection = GetRequiredService <SurfaceControllerTypeCollection>(htmlHelper); Type?surfaceController = surfaceControllerTypeCollection.SingleOrDefault(x => x == surfaceType); if (surfaceController == null) { throw new InvalidOperationException("Could not find the surface controller of type " + surfaceType.FullName); } var routeVals = new RouteValueDictionary(new { area = string.Empty }); PluginControllerMetadata metaData = PluginController.GetMetadata(surfaceController); if (!metaData.AreaName.IsNullOrWhiteSpace()) { // set the area to the plugin area if (routeVals.ContainsKey("area")) { routeVals["area"] = metaData.AreaName; } else { routeVals.Add("area", metaData.AreaName); } } return(htmlHelper.ActionLink(actionName, metaData.ControllerName, routeVals)); }
private static void RouteLocalApiController(Type controller, string umbracoPath) { var meta = PluginController.GetMetadata(controller); var url = umbracoPath + (meta.IsBackOffice ? "/BackOffice" : "") + "/Api/" + meta.ControllerName + "/{action}/{id}"; var route = RouteTable.Routes.MapHttpRoute( $"umbraco-api-{meta.ControllerName}", url, // url to match new { controller = meta.ControllerName, id = UrlParameter.Optional }, new[] { meta.ControllerNamespace }); if (route.DataTokens == null) // web api routes don't set the data tokens object { route.DataTokens = new RouteValueDictionary(); } route.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, "api"); //ensure the umbraco token is set }
private void RouteLocalApiController(Type controller, string umbracoPath) { var meta = PluginController.GetMetadata(controller); var route = RouteTable.Routes.MapHttpRoute( string.Format("umbraco-{0}-{1}", "api", meta.ControllerName), umbracoPath + "/Api/" + meta.ControllerName + "/{action}/{id}", //url to match new { controller = meta.ControllerName, id = UrlParameter.Optional }); //web api routes don't set the data tokens object if (route.DataTokens == null) { route.DataTokens = new RouteValueDictionary(); } route.DataTokens.Add("Namespaces", new[] { meta.ControllerNamespace }); //look in this namespace to create the controller route.DataTokens.Add("UseNamespaceFallback", false); //Don't look anywhere else except this namespace! route.DataTokens.Add("umbraco", "api"); //ensure the umbraco token is set }
/// <summary> /// Auto-routes all front-end api controllers /// </summary> private void AutoRouteFrontEndApiControllers(IEndpointRouteBuilder endpoints) { foreach (Type controller in _apiControllers) { PluginControllerMetadata meta = PluginController.GetMetadata(controller); // exclude back-end api controllers if (meta.IsBackOffice) { continue; } endpoints.MapUmbracoApiRoute( meta.ControllerType, _umbracoPathSegment, meta.AreaName, meta.IsBackOffice, defaultAction: string.Empty); // no default action (this is what we had before) } }
private void RouteLocalApiController(Type controller, string umbracoPath) { var meta = PluginController.GetMetadata(controller); //url to match var routePath = meta.IsBackOffice == false ? umbracoPath + "/Api/" + meta.ControllerName + "/{action}/{id}" : umbracoPath + "/BackOffice/Api/" + meta.ControllerName + "/{action}/{id}"; var route = RouteTable.Routes.MapHttpRoute( string.Format("umbraco-{0}-{1}", "api", meta.ControllerName), routePath, new { controller = meta.ControllerName, id = UrlParameter.Optional }, new[] { meta.ControllerNamespace }); //web api routes don't set the data tokens object if (route.DataTokens == null) { route.DataTokens = new RouteValueDictionary(); } route.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, "api"); //ensure the umbraco token is set }
/// <summary> /// Return the Url for a Web Api service /// </summary> /// <param name="url"></param> /// <param name="actionName"></param> /// <param name="apiControllerType"></param> /// <param name="id"></param> /// <returns></returns> public static string GetUmbracoApiService(this UrlHelper url, string actionName, Type apiControllerType, object id = null) { Mandate.ParameterNotNullOrEmpty(actionName, "actionName"); Mandate.ParameterNotNull(apiControllerType, "apiControllerType"); var area = ""; var apiController = UmbracoApiControllerResolver.Current.RegisteredUmbracoApiControllers .SingleOrDefault(x => x == apiControllerType); if (apiController == null) { throw new InvalidOperationException("Could not find the umbraco api controller of type " + apiControllerType.FullName); } var metaData = PluginController.GetMetadata(apiController); if (metaData.AreaName.IsNullOrWhiteSpace() == false) { //set the area to the plugin area area = metaData.AreaName; } return(url.GetUmbracoApiService(actionName, ControllerExtensions.GetControllerName(apiControllerType), area)); }