/// <summary> /// Call this method from the controller to perform routing. /// </summary> /// <param name="viewData">Routing view data.</param> /// <param name="oModel">Model to be passed to the view.</param> /// <returns>View URL.</returns> public static string Route(ref RoutingViewData viewData, out object oModel) { RouteTemplate template = viewData?.ActiveTemplate; if (template != null) { try { oModel = ResolveVM(template); if (oModel is IRoutable) { (oModel as IRoutable).RouteUrl(ref viewData); } else { viewData = null; } return(template.ViewUrl); } catch (Exception ex) { Trace.Fail(ex.ToString()); } } oModel = null; return(null); }
/// <summary> /// Call this method from the controller to perform routing. /// </summary> /// <param name="viewData">Routing view data.</param> /// <param name="oModel">Model to be passed to the view.</param> /// <returns>View URL.</returns> public static string Route(ref RoutingViewData viewData, out object oModel) { RouteTemplate template = viewData?.ActiveTemplate; if (template != null) { try { oModel = ResolveVM(template); if (oModel is IRoutable) { (oModel as IRoutable).RouteUrl(ref viewData); } else { viewData = null; } return(template.ViewUrl); } catch (Exception ex) { Logger.LogError($"Failed to route: {ex.Message}"); } } oModel = null; return(null); }
/// <summary> /// Call this method from the controller to perform routing. /// </summary> /// <param name="viewData">Routing view data.</param> /// <param name="oModel">Model to be passed to the view.</param> /// <returns>View URL.</returns> public static string Route(ref RoutingViewData viewData, out IRoutable oModel) { var template = viewData.ActiveTemplate; if (template != null) { try { oModel = template.VMType != null?VMController.CreateInstance(template.VMType, null) as IRoutable : null; if (oModel != null) { oModel.RouteUrl(ref viewData); } return(template.ViewUrl); } catch (Exception ex) { Trace.Fail(ex.ToString()); } } oModel = null; return(null); }
public void Routing_RouteBookDetails() { var viewData = new RoutingViewData("/index/books/book/the-martian", "/Index_cshtml", typeof(TestNavBarVM)); IRoutable model; string viewId = String.Empty; viewId = RoutableExtension.Route(ref viewData, out model); Assert.IsNotNull(viewId); Assert.AreEqual("/Index_cshtml", viewId); Assert.IsNotNull(model is TestNavBarVM); var activatedEventArgs = (model as TestNavBarVM).TestActivatedEventArgs; Assert.IsNotNull(activatedEventArgs); Assert.AreEqual("books", activatedEventArgs.Active); viewId = RoutableExtension.Route(ref viewData, out model); Assert.IsNotNull(viewId); Assert.AreEqual("/BookStore_cshtml", viewId); Assert.IsNotNull(model is TestBookStoreVM); activatedEventArgs = (model as TestBookStoreVM).TestActivatedEventArgs; Assert.IsNotNull(activatedEventArgs); Assert.AreEqual("book/the-martian", activatedEventArgs.Active); viewId = RoutableExtension.Route(ref viewData, out model); Assert.IsNotNull(viewId); Assert.AreEqual("/BookDetails_cshtml", viewId); Assert.IsNotNull(model is TestBookDetailsVM); var routedEventArgs = (model as TestBookDetailsVM).TestRoutedEventArgs; Assert.IsNotNull(routedEventArgs); Assert.AreEqual("book/the-martian", routedEventArgs.From); }
/// <summary> /// Call this method from the controller to perform routing. /// </summary> /// <param name="viewData">Routing view data.</param> /// <param name="oModel">Model to be passed to the view.</param> /// <returns>View URL.</returns> public static string Route(ref RoutingViewData viewData, out object oModel) { RouteTemplate template = viewData?.ActiveTemplate; if (template != null) { try { oModel = template.VMType != null?VMController.CreateInstance(template.VMType, null) : null; if (oModel is IRoutable) { (oModel as IRoutable).RouteUrl(ref viewData); } else { viewData = null; } return(template.ViewUrl); } catch (Exception ex) { Trace.Fail(ex.ToString()); } } oModel = null; return(null); }
public ActionResult Routing(RoutingViewData iViewData) { IRoutable model; var viewId = RoutableExtension.Route(ref iViewData, out model); if (viewId != null) { ViewData["Routing"] = iViewData; return Demo(viewId.Replace("/Demo/", ""), model); } return new EmptyResult(); }
public static string GetInitialStates(IVMFactory vmFactory, ref string path, Type entryVMType) { string result = null; try { using (var vmController = new VMController((arg1, arg2, arg3) => Task.CompletedTask, vmFactory)) { // Traverse the routing path to get initial states of all the view models involved. var vmStates = new List <string>(); if (!Path.HasExtension(path)) { var viewData = new RoutingViewData(path, null, entryVMType); RoutableExtension.Route(ref viewData, out object vm); while (vm != null) { object vmArgs = null; if (vm is IRoutable routable) { // If at the end of the path and the view model has a default route template (blank url pattern), // append a slash to the path to ensure it's correctly routed. if (path.Trim('/').Length > 0 && string.Compare(viewData.UrlPath, viewData.Root, true) == 0 && routable.RoutingState.Templates.Any(i => i.UrlPattern == "")) { path += "/"; } // Determine the "RoutingState.Origin" property value and pass it as argument to the view model // associated with the current path to set its initial state correctly. string args = routable.InitArgs(viewData); Match match = Regex.Match(args, "'RoutingState.Origin':\\s*'(.*?)'"); if (match.Success) { vmArgs = JsonConvert.DeserializeObject($"{{{match.Value}}}"); } } string vmName = vm.GetType().Name; vmStates.Add($"\"{vmName}\":{vmController.GetInitialState(vmName, vmArgs)}"); // Traverse the next path. RoutableExtension.Route(ref viewData, out vm); } result = $"{{{string.Join(",", vmStates)}}}"; } return(result); } } catch (Exception ex) { Logger.LogError($"Failed to get SSR initial states: {ex.Message}"); return(null); } }
public static string GetInitialStates(ref string path, Type entryVMType) { try { // Traverse the routing path to get initial states of all the view models involved. var vmStates = new List <string>(); if (path.Trim('/').Length > 0) { var viewData = new RoutingViewData(path, null, entryVMType); RoutableExtension.Route(ref viewData, out IRoutable vm); while (vm != null) { // If at the end of the path and the view model has a default route template (blank url pattern), // append a slash to the path to ensure it's correctly routed. if (string.Compare(viewData.UrlPath, viewData.Root, true) == 0 && vm.RoutingState.Templates.Any(i => i.UrlPattern == "")) { path += "/"; } // Determine the "RoutingState.Origin" property value and pass it as argument to the view model // associated with the current path to set its initial state correctly. object vmArgs = null; var args = vm.InitArgs(viewData); var match = Regex.Match(args, "'RoutingState.Origin':\\s*'(.*?)'"); if (match.Success) { vmArgs = JsonConvert.DeserializeObject($"{{{match.Value}}}"); } var vmName = vm.GetType().Name; vmStates.Add($"\"{vmName}\":{VMController.GetInitialState(vmName, vmArgs)}"); // Traverse the next path. RoutableExtension.Route(ref viewData, out vm); } } return($"{{{string.Join(",", vmStates)}}}"); } catch (Exception ex) { System.Diagnostics.Trace.Fail(ex.ToString()); return(null); } }
/// <summary> /// Performs routing. The URL path is given inside the view data, along with the initial route template to start from. /// This is a recursive method that will be called again by the nested views until the route is resolved. /// </summary> /// <param name="routable">Routable view model.</param> /// <param name="viewData">Routing view data.</param> public static void RouteUrl(this IRoutable routable, ref RoutingViewData viewData) { var routingState = routable.RoutingState; if (routingState == null) { return; } viewData.ActiveTemplate = null; routingState.Origin = viewData.Origin; if (routingState.Templates != null) { viewData.Root = viewData.Root?.TrimEnd('/') + "/" + routingState.Root; var bestMatch = MatchTemplate(routingState.Templates, viewData.UrlPath, viewData.Root); Trace.WriteLine($"[dotNetify] Matched route {viewData.UrlPath}: {bestMatch?.Value}"); if (bestMatch != null) { viewData.ActiveTemplate = bestMatch.Value.Key; if (bestMatch.Value.Value != null && bestMatch.Value.Key.VMType != null) { routingState.Active = bestMatch.Value.Value; } else { routingState.Active = null; } } // If there's no match, but the Active path has a default value, resolve its route. else if (routingState.Active != null) { bestMatch = MatchTemplate(routingState.Templates, routingState.Active, null); if (bestMatch != null) { viewData.ActiveTemplate = bestMatch.Value.Key; } } } // Pass along information from this view to the next nested view. viewData.Origin = routingState.Active; }
/// <summary> /// Call this method from the controller to perform routing. /// </summary> /// <param name="iViewData">Routing view data.</param> /// <param name="oModel">Model to be passed to the view.</param> /// <returns>View URL.</returns> public static string Route(ref RoutingViewData iViewData, out IRoutable oModel) { var template = iViewData.ActiveTemplate; if (template != null) { try { oModel = template.VMType != null ? Activator.CreateInstance(template.VMType) as IRoutable : null; if (oModel != null) oModel.RouteUrl(ref iViewData); return template.ViewUrl; } catch (Exception ex) { Trace.Fail(ex.ToString()); } } oModel = null; return null; }
/// <summary> /// Performs routing. The URL path is given inside the view data, along with the initial route template to start from. /// This is a recursive method that will be called again by the nested views until the route is resolved. /// </summary> /// <param name="iRoutable">Routable view model.</param> /// <param name="iViewData">Routing view data.</param> public static void RouteUrl(this IRoutable iRoutable, ref RoutingViewData iViewData) { var routingState = iRoutable.RoutingState; iViewData.ActiveTemplate = null; routingState.Origin = iViewData.Origin; if (routingState.Templates != null) { iViewData.Root = iViewData.Root + "/" + routingState.Root; var bestMatch = MatchTemplate(routingState.Templates, iViewData.UrlPath, iViewData.Root); if (bestMatch != null) { iViewData.ActiveTemplate = bestMatch.Value.Key; if (bestMatch.Value.Value != null && typeof(IRoutable).IsAssignableFrom(bestMatch.Value.Key.VMType)) routingState.Active = bestMatch.Value.Value; else routingState.Active = null; } // If there's no match, but the Active path has a default value, resolve its route. else if (routingState.Active != null) { bestMatch = MatchTemplate(routingState.Templates, routingState.Active, null); if (bestMatch != null) iViewData.ActiveTemplate = bestMatch.Value.Key; } } // Pass along information from this view to the next nested view. iViewData.Origin = routingState.Active; }
/// <summary> /// Performs routing. The URL path is given inside the view data, along with the initial route template to start from. /// This is a recursive method that will be called again by the nested views until the route is resolved. /// </summary> /// <param name="routable">Routable view model.</param> /// <param name="viewData">Routing view data.</param> public static void RouteUrl(this IRoutable routable, ref RoutingViewData viewData) { var routingState = routable.RoutingState; if (routingState == null) return; viewData.ActiveTemplate = null; routingState.Origin = viewData.Origin; if (routingState.Templates != null) { viewData.Root = viewData.Root + "/" + routingState.Root; var bestMatch = MatchTemplate(routingState.Templates, viewData.UrlPath, viewData.Root); Trace.WriteLine($"[DEBUG] Matched route {viewData.UrlPath}: {bestMatch?.Value}"); if (bestMatch != null) { viewData.ActiveTemplate = bestMatch.Value.Key; if (bestMatch.Value.Value != null && typeof(IRoutable).IsAssignableFrom(bestMatch.Value.Key.VMType)) routingState.Active = bestMatch.Value.Value; else routingState.Active = null; } // If there's no match, but the Active path has a default value, resolve its route. else if (routingState.Active != null) { bestMatch = MatchTemplate(routingState.Templates, routingState.Active, null); if (bestMatch != null) viewData.ActiveTemplate = bestMatch.Value.Key; } } // Pass along information from this view to the next nested view. viewData.Origin = routingState.Active; }