private void Initalize() { UrlMappingConfig config = UrlMappingConfig.Instance; _provider = ServiceLocator.Instance.Resolve <IUrlMappingProvider>(); _noMatchAction = config.NoMatchAction; _noMatchRedirectPage = config.NoMatchRedirectUrl; _automaticallyUpdateFormAction = config.AutoUpdateFormAction; _qsBehavior = config.IncomingQueryStringBehavior; _processingEvent = config.UrlProcessingEvent; if (_provider != null) { _provider.Initialize(config); } // save to config config.Provider = _provider; }
private static UrlMappingItem getUrlInfo(XmlNode node, NavigationItem menuItem, int index, int subIndex, int subsubIndex, IncomingQueryStringBehavior incomingQueryStringBehavior) { string name = XmlUtil.GetStringAttribute(node, "name", string.Empty); string urlTemplate = XmlUtil.GetStringAttribute(node, "template", string.Empty); if (string.IsNullOrEmpty(urlTemplate)) { throw new UrlMappingException("There is an XmlUrlMappingModule error. All <url> tags in the mapping file require a 'template' attribute."); } string redirection = Utility.GetHref(XmlUtil.GetStringAttribute(node, "href", string.Empty)); // still here, we can create the item and add to the collection UrlMappingItem item = Utility.CreateTemplatedMappingItem( name, urlTemplate, redirection, incomingQueryStringBehavior ); item.UrlTemplate = urlTemplate; // set custom attributes foreach (XmlAttribute attr in node.Attributes) { item[attr.Name] = attr.Value; } if (XmlUtil.GetStringAttribute(node, "index", string.Empty) == "?") { item.Index = null; } else { item.Index = index; } if (XmlUtil.GetStringAttribute(node, "subindex", string.Empty) == "?") { item.SubIndex = null; } else { item.SubIndex = subIndex; } if (XmlUtil.GetStringAttribute(node, "subsubindex", string.Empty) == "?") { item.SubsubIndex = null; } else { item.SubsubIndex = subsubIndex; } item.Title = XmlUtil.GetStringAttribute(node, "title", menuItem.Title); item.Id = XmlUtil.GetStringAttribute(node, "id", null); item.Action = XmlUtil.GetStringAttribute(node, "action", null); return(item); }
public static void ParseXml(string file, UrlMappingItemCollection routes, Dictionary <int, NavigationItem> menuItems, IncomingQueryStringBehavior incomingQueryStringBehavior) { if (!File.Exists(file)) { return; } XmlDocument xml = new XmlDocument(); try { xml.Load(file); } catch (Exception ex) { throw new UrlMappingException("The error occurred while loading the route files. A virtual path is required and the file must be well-formed.", ex); } menuItems.Clear(); int i = -1, j = -1, k = -1; foreach (XmlNode node in xml.DocumentElement.ChildNodes) { if (node.Name == "menu") { i++; NavigationItem menuItem = getMenuItem(node); menuItem.Children = new Dictionary <int, NavigationItem>(); menuItems[i] = menuItem; foreach (XmlNode subNode in node.ChildNodes) { if (subNode.Name == "menu") { j++; NavigationItem sub_menuItem = getMenuItem(subNode); sub_menuItem.Children = new Dictionary <int, NavigationItem>(); menuItems[i].Children[j] = sub_menuItem; foreach (XmlNode subsubNode in subNode.ChildNodes) { if (subsubNode.Name == "menu") { k++; NavigationItem subsub_menuItem = getMenuItem(subsubNode); sub_menuItem.Children[k] = subsub_menuItem; foreach (XmlNode last_node in subsubNode.ChildNodes) { if (last_node.Name == "url") { UrlMappingItem url = getUrlInfo(last_node, subsub_menuItem, i, j, k, incomingQueryStringBehavior); routes.Add(url); } } } else if (subsubNode.Name == "url") { UrlMappingItem url = getUrlInfo(subsubNode, sub_menuItem, i, j, -1, incomingQueryStringBehavior); routes.Add(url); } } } else if (subNode.Name == "url") { UrlMappingItem url = getUrlInfo(subNode, menuItem, i, -1, -1, incomingQueryStringBehavior); routes.Add(url); } } } else if (node.Name == "url") { UrlMappingItem url = getUrlInfo(node, new NavigationItem(), -1, -1, -1, incomingQueryStringBehavior); routes.Add(url); } } }
/// <summary> /// Return a regular expression translated from the given templated URL. /// </summary> /// <param name="templatedUrl">A URL pattern relative to the application, with [TokenNames] included for dynamic matching</param> /// <param name="qsBehavior">defines how the UrlMappingModule should treat querystring values on an incoming URL for pattern matching; this is typically provided through declarative configuration</param> /// <returns>A regular expression as a <see cref="Regex" /> object</returns> /// <remarks> /// <para> /// A templated URL uses token names surrounded by [SquareBrackets] to provide for dynamic /// matching and parsing. /// For example, the URL template: /// <i>Reports/[ID]/[Action].aspx</i> /// translates to the following regular expression: /// <i>Reports/(?<ID>[a-zA-Z0-9_+%]*)/(?<Action>[a-zA-Z0-9_+%]*).aspx"</i> /// </para> /// <para> /// The regular expression is then used by the UrlMappingModule to match incoming URLs. /// If a match is found, token names and values are automatically appended to the /// redirection URL as querystring arguments. So, given the above templated URL string /// of <i>Reports/[ID]/[Action].aspx</i> with a Redirection defined as /// <i>ReportAction.aspx</i>, an incoming URL of <i>Reports/47/Edit.aspx</i> /// is redirected by the UrlMappingModule to the following: /// <i>ReportAction.aspx?ID=47&Action=Edit</i>. /// </para> /// </remarks> public static Regex CreateTemplatedMappingRegex(string templatedUrl, IncomingQueryStringBehavior qsBehavior) { // return a case-insensitive regex that must match the url completely return CreateTemplatedMappingRegex(templatedUrl, false, true, qsBehavior); }
/// <summary> /// Creates a <see cref="UrlMappingItem" /> given a name, templated URL string, and redirection string. /// </summary> /// <param name="name">A name for this mapping item</param> /// <param name="templatedUrl">A template for URLs to be matched</param> /// <param name="redirection">The redirection that the UrlMappingModule should apply when incoming URLs match the template.</param> /// <param name="qsBehavior">defines how the UrlMappingModule should treat querystring values on an incoming URL for pattern matching; this is typically provided through declarative configuration</param> /// <returns>The created <see cref="UrlMappingItem" /></returns> /// <remarks> /// <para> /// The template URL string is relative to the web application and may or may not include /// the "~/" characters at the beginning. The template may indicate an exact URL to match, /// for example <i>Reports/Summary.aspx</i> or may include token names surrounded /// by [SquareBrackets] for dynamic matching, such as <i>Reports/[ID]/[Action].aspx</i>. /// When dynamic templates are matched in runtime by the UrlMappingModule, dynamic tokens /// are appended to the redirection string as querystring items, /// such as <i>?ID=<i>xxx</i>&Action=<i>xxx</i></i>. /// </para> /// <para> /// The redirection string may be an absolute URL, such as <i>http://www.microsoft.com</i>, /// a server-relative URL beginning with a "/", such as <i>/AnotherAppOnThisServer/page.aspx</i>, /// or an application-relative URL to a concrete resource, optionally beginning with a "~/", such as /// <i>~/ReportSummary.aspx</i> or <i>ReportSummary.aspx</i>. /// </para> /// </remarks> public static UrlMappingItem CreateTemplatedMappingItem(string name, string templatedUrl, string redirection, IncomingQueryStringBehavior qsBehavior) { UrlMappingItem item = new UrlMappingItem(name, CreateTemplatedMappingRegex(templatedUrl, qsBehavior), redirection); item.UrlTemplate = templatedUrl; return item; }
/// <summary> /// Return a regular expression translated from the given templated URL. /// </summary> /// <param name="templatedUrl">A URL pattern relative to the application, with [TokenNames] included for dynamic matching</param> /// <param name="caseSensitive"><i>true</i> if the returned expression should be case sensitive, <i>false</i> if not</param> /// <param name="matchCompletely"><i>true</i> if the returned expression should include beginning and ending anchors, ensuring that a match will require the complete URL and not a portion of it</param> /// <param name="qsBehavior">defines how the UrlMappingModule should treat querystring values on an incoming URL for pattern matching; this is typically provided through declarative configuration</param> /// <returns>A regular expression as a <see cref="Regex" /> object</returns> /// <remarks> /// <para> /// A templated URL uses token names surrounded by [SquareBrackets] to provide for dynamic /// matching and parsing. /// For example, the URL template: /// <i>Reports/[ID]/[Action].aspx</i> /// translates to the following regular expression: /// <i>Reports/(?<ID>[a-zA-Z0-9_+%]*)/(?<Action>[a-zA-Z0-9_+%]*).aspx"</i> /// </para> /// <para> /// The regular expression is then used by the UrlMappingModule to match incoming URLs. /// If a match is found, token names and values are automatically appended to the /// redirection URL as querystring arguments. So, given the above templated URL string /// of <i>Reports/[ID]/[Action].aspx</i> with a Redirection defined as /// <i>ReportAction.aspx</i>, an incoming URL of <i>Reports/47/Edit.aspx</i> /// is redirected by the UrlMappingModule to the following: /// <i>ReportAction.aspx?ID=47&Action=Edit</i>. /// </para> /// </remarks> public static Regex CreateTemplatedMappingRegex(string templatedUrl, bool caseSensitive, bool matchCompletely, IncomingQueryStringBehavior qsBehavior) { // return a regex that parses an app-relative url string and constructs an appropriate // Regular Expression for matching it; the template may include tokens in the form // of [TokenItem] which are matched as groups; // e.g. the url template "Reports/Display/[ID].aspx" becomes the regular expression: // Reports/Display/(?<ID>[a-zA-Z0-9_+%]*).aspx" // if matchCompletely is true, the regex is anchored; if false, the match can occur // anywhere within the url // options for the returned regular expression RegexOptions options = (caseSensitive ? RegexOptions.None : RegexOptions.IgnoreCase); // if the templatedUrl contains a querystring ? and we're incorporating querystring values in the regex //then escape it if (qsBehavior == IncomingQueryStringBehavior.Include) templatedUrl = templatedUrl.Replace("?", "\\?"); // use a regex now to parse for [Tokens] Regex r = new Regex(@"(\[[a-zA-Z0-9_]*\])"); MatchCollection matches = r.Matches(templatedUrl); string s = templatedUrl; foreach (Match m in matches) { if (m.Value.Length == 2) { s = s.Replace(m.Value, @"(?<_pre_>[/\-~?.a-zA-Z0-9_\u00a4-\uffe5+]*)"); } else { string tokenName = m.Value.Substring(1, m.Value.Length - 2); s = s.Replace(m.Value, string.Format(@"(?<{0}>[\-~?a-zA-Z0-9_\u00a4-\uffe5+]*)", tokenName)); } } // if the matchCompletely option is desired, add anchors to the regex string if (matchCompletely) s = "^" + s + "$"; // now construct and return the regular expression to test for these kinds of URLs return new Regex(s, options); }
private void Initalize() { UrlMappingConfig config = UrlMappingConfig.Instance; _provider = ServiceLocator.Instance.Resolve<IUrlMappingProvider>(); _noMatchAction = config.NoMatchAction; _noMatchRedirectPage = config.NoMatchRedirectUrl; _automaticallyUpdateFormAction = config.AutoUpdateFormAction; _qsBehavior = config.IncomingQueryStringBehavior; _processingEvent = config.UrlProcessingEvent; if (_provider != null) { _provider.Initialize(config); } // save to config config.Provider = _provider; }
private static UrlMappingItem getUrlInfo(XmlNode node, NavigationItem menuItem, int index, int subIndex, int subsubIndex, IncomingQueryStringBehavior incomingQueryStringBehavior) { string name = XmlUtil.GetStringAttribute(node, "name", string.Empty); string urlTemplate = XmlUtil.GetStringAttribute(node, "template", string.Empty); if (string.IsNullOrEmpty(urlTemplate)) throw new UrlMappingException("There is an XmlUrlMappingModule error. All <url> tags in the mapping file require a 'template' attribute."); string redirection = Utility.GetHref(XmlUtil.GetStringAttribute(node, "href", string.Empty)); // still here, we can create the item and add to the collection UrlMappingItem item = Utility.CreateTemplatedMappingItem( name, urlTemplate, redirection, incomingQueryStringBehavior ); item.UrlTemplate = urlTemplate; // set custom attributes foreach (XmlAttribute attr in node.Attributes) { item[attr.Name] = attr.Value; } if (XmlUtil.GetStringAttribute(node, "index", string.Empty) == "?") item.Index = null; else item.Index = index; if (XmlUtil.GetStringAttribute(node, "subindex", string.Empty) == "?") item.SubIndex = null; else item.SubIndex = subIndex; if (XmlUtil.GetStringAttribute(node, "subsubindex", string.Empty) == "?") item.SubsubIndex = null; else item.SubsubIndex = subsubIndex; item.Title = XmlUtil.GetStringAttribute(node, "title", menuItem.Title); item.Id = XmlUtil.GetStringAttribute(node, "id", null); item.Action = XmlUtil.GetStringAttribute(node, "action", null); return item; }
public static void ParseXml(string file, UrlMappingItemCollection routes, Dictionary<int, NavigationItem> menuItems, IncomingQueryStringBehavior incomingQueryStringBehavior) { if (!File.Exists(file)) return; XmlDocument xml = new XmlDocument(); try { xml.Load(file); } catch (Exception ex) { throw new UrlMappingException("The error occurred while loading the route files. A virtual path is required and the file must be well-formed.", ex); } menuItems.Clear(); int i = -1, j = -1, k = -1; foreach (XmlNode node in xml.DocumentElement.ChildNodes) { if (node.Name == "menu") { i++; NavigationItem menuItem = getMenuItem(node); menuItem.Children = new Dictionary<int, NavigationItem>(); menuItems[i] = menuItem; foreach (XmlNode subNode in node.ChildNodes) { if (subNode.Name == "menu") { j++; NavigationItem sub_menuItem = getMenuItem(subNode); sub_menuItem.Children = new Dictionary<int, NavigationItem>(); menuItems[i].Children[j] = sub_menuItem; foreach (XmlNode subsubNode in subNode.ChildNodes) { if (subsubNode.Name == "menu") { k++; NavigationItem subsub_menuItem = getMenuItem(subsubNode); sub_menuItem.Children[k] = subsub_menuItem; foreach (XmlNode last_node in subsubNode.ChildNodes) { if (last_node.Name == "url") { UrlMappingItem url = getUrlInfo(last_node, subsub_menuItem, i, j, k, incomingQueryStringBehavior); routes.Add(url); } } } else if (subsubNode.Name == "url") { UrlMappingItem url = getUrlInfo(subsubNode, sub_menuItem, i, j, -1, incomingQueryStringBehavior); routes.Add(url); } } } else if (subNode.Name == "url") { UrlMappingItem url = getUrlInfo(subNode, menuItem, i, -1, -1, incomingQueryStringBehavior); routes.Add(url); } } } else if (node.Name == "url") { UrlMappingItem url = getUrlInfo(node, new NavigationItem(), -1, -1, -1, incomingQueryStringBehavior); routes.Add(url); } } }
/// <summary> /// Return a regular expression translated from the given templated URL. /// </summary> /// <param name="templatedUrl">A URL pattern relative to the application, with [TokenNames] included for dynamic matching</param> /// <param name="qsBehavior">defines how the UrlMappingModule should treat querystring values on an incoming URL for pattern matching; this is typically provided through declarative configuration</param> /// <returns>A regular expression as a <see cref="Regex" /> object</returns> /// <remarks> /// <para> /// A templated URL uses token names surrounded by [SquareBrackets] to provide for dynamic /// matching and parsing. /// For example, the URL template: /// <i>Reports/[ID]/[Action].aspx</i> /// translates to the following regular expression: /// <i>Reports/(?<ID>[a-zA-Z0-9_+%]*)/(?<Action>[a-zA-Z0-9_+%]*).aspx"</i> /// </para> /// <para> /// The regular expression is then used by the UrlMappingModule to match incoming URLs. /// If a match is found, token names and values are automatically appended to the /// redirection URL as querystring arguments. So, given the above templated URL string /// of <i>Reports/[ID]/[Action].aspx</i> with a Redirection defined as /// <i>ReportAction.aspx</i>, an incoming URL of <i>Reports/47/Edit.aspx</i> /// is redirected by the UrlMappingModule to the following: /// <i>ReportAction.aspx?ID=47&Action=Edit</i>. /// </para> /// </remarks> public static Regex CreateTemplatedMappingRegex(string templatedUrl, IncomingQueryStringBehavior qsBehavior) { // return a case-insensitive regex that must match the url completely return(CreateTemplatedMappingRegex(templatedUrl, false, true, qsBehavior)); }
/// <summary> /// Creates a <see cref="UrlMappingItem" /> given a name, templated URL string, and redirection string. /// </summary> /// <param name="name">A name for this mapping item</param> /// <param name="templatedUrl">A template for URLs to be matched</param> /// <param name="redirection">The redirection that the UrlMappingModule should apply when incoming URLs match the template.</param> /// <param name="qsBehavior">defines how the UrlMappingModule should treat querystring values on an incoming URL for pattern matching; this is typically provided through declarative configuration</param> /// <returns>The created <see cref="UrlMappingItem" /></returns> /// <remarks> /// <para> /// The template URL string is relative to the web application and may or may not include /// the "~/" characters at the beginning. The template may indicate an exact URL to match, /// for example <i>Reports/Summary.aspx</i> or may include token names surrounded /// by [SquareBrackets] for dynamic matching, such as <i>Reports/[ID]/[Action].aspx</i>. /// When dynamic templates are matched in runtime by the UrlMappingModule, dynamic tokens /// are appended to the redirection string as querystring items, /// such as <i>?ID=<i>xxx</i>&Action=<i>xxx</i></i>. /// </para> /// <para> /// The redirection string may be an absolute URL, such as <i>http://www.microsoft.com</i>, /// a server-relative URL beginning with a "/", such as <i>/AnotherAppOnThisServer/page.aspx</i>, /// or an application-relative URL to a concrete resource, optionally beginning with a "~/", such as /// <i>~/ReportSummary.aspx</i> or <i>ReportSummary.aspx</i>. /// </para> /// </remarks> public static UrlMappingItem CreateTemplatedMappingItem(string name, string templatedUrl, string redirection, IncomingQueryStringBehavior qsBehavior) { UrlMappingItem item = new UrlMappingItem(name, CreateTemplatedMappingRegex(templatedUrl, qsBehavior), redirection); item.UrlTemplate = templatedUrl; return(item); }
/// <summary> /// Return a regular expression translated from the given templated URL. /// </summary> /// <param name="templatedUrl">A URL pattern relative to the application, with [TokenNames] included for dynamic matching</param> /// <param name="caseSensitive"><i>true</i> if the returned expression should be case sensitive, <i>false</i> if not</param> /// <param name="matchCompletely"><i>true</i> if the returned expression should include beginning and ending anchors, ensuring that a match will require the complete URL and not a portion of it</param> /// <param name="qsBehavior">defines how the UrlMappingModule should treat querystring values on an incoming URL for pattern matching; this is typically provided through declarative configuration</param> /// <returns>A regular expression as a <see cref="Regex" /> object</returns> /// <remarks> /// <para> /// A templated URL uses token names surrounded by [SquareBrackets] to provide for dynamic /// matching and parsing. /// For example, the URL template: /// <i>Reports/[ID]/[Action].aspx</i> /// translates to the following regular expression: /// <i>Reports/(?<ID>[a-zA-Z0-9_+%]*)/(?<Action>[a-zA-Z0-9_+%]*).aspx"</i> /// </para> /// <para> /// The regular expression is then used by the UrlMappingModule to match incoming URLs. /// If a match is found, token names and values are automatically appended to the /// redirection URL as querystring arguments. So, given the above templated URL string /// of <i>Reports/[ID]/[Action].aspx</i> with a Redirection defined as /// <i>ReportAction.aspx</i>, an incoming URL of <i>Reports/47/Edit.aspx</i> /// is redirected by the UrlMappingModule to the following: /// <i>ReportAction.aspx?ID=47&Action=Edit</i>. /// </para> /// </remarks> public static Regex CreateTemplatedMappingRegex(string templatedUrl, bool caseSensitive, bool matchCompletely, IncomingQueryStringBehavior qsBehavior) { // return a regex that parses an app-relative url string and constructs an appropriate // Regular Expression for matching it; the template may include tokens in the form // of [TokenItem] which are matched as groups; // e.g. the url template "Reports/Display/[ID].aspx" becomes the regular expression: // Reports/Display/(?<ID>[a-zA-Z0-9_+%]*).aspx" // if matchCompletely is true, the regex is anchored; if false, the match can occur // anywhere within the url // options for the returned regular expression RegexOptions options = (caseSensitive ? RegexOptions.None : RegexOptions.IgnoreCase); // if the templatedUrl contains a querystring ? and we're incorporating querystring values in the regex //then escape it if (qsBehavior == IncomingQueryStringBehavior.Include) { templatedUrl = templatedUrl.Replace("?", "\\?"); } // use a regex now to parse for [Tokens] Regex r = new Regex(@"(\[[a-zA-Z0-9_]*\])"); MatchCollection matches = r.Matches(templatedUrl); string s = templatedUrl; foreach (Match m in matches) { if (m.Value.Length == 2) { s = s.Replace(m.Value, @"(?<_pre_>[/\-~?.a-zA-Z0-9_\u00a4-\uffe5+]*)"); } else { string tokenName = m.Value.Substring(1, m.Value.Length - 2); s = s.Replace(m.Value, string.Format(@"(?<{0}>[\-~?a-zA-Z0-9_\u00a4-\uffe5+]*)", tokenName)); } } // if the matchCompletely option is desired, add anchors to the regex string if (matchCompletely) { s = "^" + s + "$"; } // now construct and return the regular expression to test for these kinds of URLs return(new Regex(s, options)); }