/// <summary> /// Adds a PageRoute with DataRoute functionality for providing data to routes in a classic ASP.Net application /// </summary> /// <typeparam name="TData">The type of the content data attached by the PageDataRoute</typeparam> /// <param name="routes">The route collection</param> /// <param name="name">Name of the route table entry</param> /// <param name="url">The url matching pattern</param> /// <param name="pageUrl">The url of the .aspx page template</param> /// <returns>The PageDataRoute that was created and registered</returns> static public DataRoute <TData> AddPageDataRoute <TData>(this RouteCollection routes, string name, string url, string pageUrl) where TData : class, new() { ContentTypeHierarchy.RegisterType(typeof(TData)); var route = new DataRoute <TData>(url, new RouteValueDictionary(), new PageRouteHandler(pageUrl)); routes.Add(name, route); return(route); }
/// <summary> /// Add a DataRoute to an RouteCollection with route name, url pattern, default values and constraints /// </summary> /// <typeparam name="TData">The type of the content data attached by the DataRoute</typeparam> /// <param name="routes">A RouteCollection to add the route to</param> /// <param name="name">Name of the route table entry</param> /// <param name="url">The url matching pattern</param> /// <param name="defaults">Default values for unmatched pattern elements</param> /// <param name="constraints">Constraints for when the route should match</param> /// <returns>The DataRoute that was created and registered</returns> static public DataRoute <TData> AddDataRoute <TData>(this RouteCollection routes, string name, string url, object defaults, object constraints) where TData : class, new() { ValidateRouteSpec(name, typeof(TData), url, defaults); ContentTypeHierarchy.RegisterType(typeof(TData)); var route = new DataRoute <TData>(url, new RouteValueDictionary(defaults), new RouteValueDictionary(constraints), new MvcRouteHandler()); routes.Add(name, route); return(route); }
/// <summary> /// Adds a route to the <see cref="IRouteBuilder"/> configured for data fetching, with the specified name, template, default values, and /// data tokens. /// </summary> /// <param name="routeBuilder">The <see cref="IRouteBuilder"/> to add the route to.</param> /// <param name="name">The name of the route.</param> /// <param name="template">The URL pattern of the route.</param> /// <param name="defaults"> /// An object that contains default values for route parameters. The object's properties represent the names /// and values of the default values. /// </param> /// <param name="constraints"> /// An object that contains constraints for the route. The object's properties represent the names and values /// of the constraints. /// </param> /// <param name="dataTokens"> /// An object that contains data tokens for the route. The object's properties represent the names and values /// of the data tokens. /// </param> /// <param name="writePermission"> /// A permission object which specifies who can create or edit the content item via this route /// </param> /// <param name="divertOverride"> /// A function which checks whether to switch out the default inner router with one which diverts the user /// to an editor controller /// </param> /// <returns>A reference to this instance after the operation has completed.</returns> public static IRouteBuilder MapDataRoute <T>( this IRouteBuilder routeBuilder, string name, string template, object defaults = null, object constraints = null, object dataTokens = null, ContentPermission writePermission = null, DiversionStrategy divertOverride = null) where T : class, new() { if (routeBuilder.DefaultHandler == null) { throw new InvalidOperationException("Default handler must be set"); } var inlineConstraintResolver = (IInlineConstraintResolver)routeBuilder .ServiceProvider .GetService(typeof(IInlineConstraintResolver)); // Interpose a DataFetchingRouter between the classic Route and the DefaultHandler, which // tries to fetch the data for the route var dataFetchingRouter = new DataFetchingRouter <T>(routeBuilder.DefaultHandler, false, writePermission, divertOverride); var dataRoute = new DataRoute( dataFetchingRouter, name, template, new RouteValueDictionary(defaults), new RouteValueDictionary(constraints), new RouteValueDictionary(dataTokens), inlineConstraintResolver); routeBuilder.Routes.Add(dataRoute); // Record the data route on Lynicon's internal RouteCollection used for reverse url generation if (ContentMap.Instance.RouteCollection == null) { ContentMap.Instance.RouteCollection = new RouteCollection(); } ContentMap.Instance.RouteCollection.Add(dataRoute); Type registerType = typeof(T); if (registerType.IsGenericType() && registerType.GetGenericTypeDefinition() == typeof(List <>)) { registerType = registerType.GetGenericArguments()[0]; } ContentTypeHierarchy.RegisterType(registerType); return(routeBuilder); }
/// <summary> /// Add a DataRoute to an RouteCollection with route name, url pattern, default values and constraints /// </summary> /// <typeparam name="TData">The type of the content data attached by the DataRoute</typeparam> /// <param name="routes">A RouteCollection to add the route to</param> /// <param name="name">Name of the route table entry</param> /// <param name="url">The url matching pattern</param> /// <param name="defaults">Default values for unmatched pattern elements</param> /// <param name="constraints">Constraints for when the route should match</param> /// <param name="dataTokens">Data tokens to add to the route</param> /// <param name="redirectOverride">An editor redirect to use with this route</param> /// <returns>The DataRoute that was created and registered</returns> static public DataRoute <TData> AddDataRoute <TData>(this RouteCollection routes, string name, string url, object defaults, object constraints, object dataTokens, IEditorRedirect redirectOverride) where TData : class, new() { ValidateRouteSpec(name, typeof(TData), url, defaults); ContentTypeHierarchy.RegisterType(typeof(TData)); var route = new DataRoute <TData>(url, new RouteValueDictionary(defaults), new RouteValueDictionary(constraints), new RouteValueDictionary(dataTokens), new MvcRouteHandler()); if (redirectOverride != null) { route.RedirectOverride = redirectOverride; } routes.Add(name, route); return(route); }
/// <summary> /// Add a DataRoute to an AreaRegistractionContext with route name, url pattern, default values and specific EditorRedirect to use /// </summary> /// <typeparam name="TData">The type of the content data attached by the DataRoute</typeparam> /// <param name="areaReg">An AreaRegistrationContext</param> /// <param name="name">Name of the route table entry</param> /// <param name="url">The url matching pattern</param> /// <param name="defaults">Default values for unmatched pattern elements</param> /// <param name="constraints">Constraints for when the route should match</param> /// <param name="dataTokens">Data tokens to add to the route</param> /// <param name="redirectOverride">An editor redirect to use with this route</param> /// <returns>The DataRoute that was created and registered</returns> static public DataRoute <TData> AddDataRoute <TData>(this AreaRegistrationContext areaReg, string name, string url, object defaults, object constraints, object dataTokens, IEditorRedirect redirectOverride) where TData : class, new() { ValidateRouteSpec(name, typeof(TData), url, defaults); ContentTypeHierarchy.RegisterType(typeof(TData)); DataRoute <TData> route = areaReg.Routes.AddDataRoute <TData>(name, url, defaults, constraints, dataTokens, redirectOverride); route.DataTokens["area"] = areaReg.AreaName; // disabling the namespace lookup fallback mechanism keeps this areas from accidentally picking up // controllers belonging to other areas //bool useNamespaceFallback = (namespaces == null || namespaces.Length == 0); //route.DataTokens["UseNamespaceFallback"] = useNamespaceFallback; return(route); }
/// <summary> /// Adds a route to the <see cref="IRouteBuilder"/> configured for data fetching, with the specified name, template, default values, and /// data tokens. /// </summary> /// <param name="routeBuilder">The <see cref="IRouteBuilder"/> to add the route to.</param> /// <param name="name">The name of the route.</param> /// <param name="template">The URL pattern of the route.</param> /// <param name="defaults"> /// An object that contains default values for route parameters. The object's properties represent the names /// and values of the default values. /// </param> /// <param name="constraints"> /// An object that contains constraints for the route. The object's properties represent the names and values /// of the constraints. /// </param> /// <param name="dataTokens"> /// An object that contains data tokens for the route. The object's properties represent the names and values /// of the data tokens. /// </param> /// <param name="divertOverride"> /// A function which checks whether to switch out the default inner router with one which diverts the user /// to an editor controller /// </param> /// <returns>A reference to this instance after the operation has completed.</returns> public static IRouteBuilder MapDataRoute <T>( this IRouteBuilder routeBuilder, string name, string template, object defaults, object constraints, object dataTokens, Func <IRouter, RouteContext, object, IRouter> divertOverride) where T : class, new() { if (routeBuilder.DefaultHandler == null) { throw new InvalidOperationException("Default handler must be set"); } var inlineConstraintResolver = (IInlineConstraintResolver)routeBuilder .ServiceProvider .GetService(typeof(IInlineConstraintResolver)); // Interpose a DataFetchingRouter between the classic Route and the DefaultHandler, which // tries to fetch the data for the route var dataFetchingRouter = new DataFetchingRouter <T>(routeBuilder.DefaultHandler, false, divertOverride); var dataRoute = new DataRoute( dataFetchingRouter, name, template, new RouteValueDictionary(defaults), new RouteValueDictionary(constraints), new RouteValueDictionary(dataTokens), inlineConstraintResolver); routeBuilder.Routes.Add(dataRoute); // Record the data route on Lynicon's internal RouteCollection used for reverse url generation if (ContentMap.Instance.RouteCollection == null) { ContentMap.Instance.RouteCollection = new RouteCollection(); } ContentMap.Instance.RouteCollection.Add(dataRoute); ContentTypeHierarchy.RegisterType(typeof(T)); return(routeBuilder); }
public static IEnumerable <string> GetTemplatePatterns(this DataRoute route, RouteData rd) { string sTemplate = route.RouteTemplate; var template = TemplateParser.Parse(sTemplate); var sbPatt = new StringBuilder(); foreach (string pattEl in sTemplate.Split('{')) { if (!pattEl.Contains("}")) { sbPatt.Append(pattEl); continue; } string key = pattEl.UpTo("}"); string remaining = pattEl.After("}"); bool isCatchAll = key.StartsWith("*"); if (isCatchAll) { key = key.Substring(1); } key = key.UpTo(":").UpTo("=").UpTo("?"); // trim off optional marker,constraints or defaults if (key == "action") { var actions = ContentTypeHierarchy.ControllerActions[rd.Values["controller"].ToString()]; if (!actions.Contains(rd.Values["action"].ToString().ToLower())) // if keyOutputs["action"] starts with "?" it has a default value and can be omitted, so the default action is assumed { continue; } sbPatt.Append("{"); sbPatt.Append(actions.Join("|")); sbPatt.Append("}"); } else { string keyVal = ""; if (rd != null && rd.Values.ContainsKey(key)) { keyVal = rd.Values[key].ToString(); } if (key.StartsWith("_")) { if (isCatchAll) { sbPatt.Append("{/" + keyVal + "}"); // catchall, can be empty and contain / } else if (template.GetParameter(key).IsOptional) { sbPatt.Append("{?" + keyVal + "}"); // mandatory, can't be empty, no /s } else { sbPatt.Append("{*" + keyVal + "}"); // optional, can be empty at RH end of url, no /s } } else { sbPatt.Append(keyVal == "" ? "_" + key + "_" : keyVal); // if no value supplied, use key as a dummy url element } } sbPatt.Append(remaining); } string ps = Regex.Replace(sbPatt.ToString(), "/+", "/"); ps = Regex.Replace(ps, "/$", ""); yield return(ps); }