/// <summary> /// /// </summary> /// <param name="urlNodes"></param> /// <param name="urlParts"></param> /// <param name="methodInfo"></param> /// <param name="url">The uriginal url - this is needed to get the real parameter before splitting. Due to the split we lost the seperator char</param> /// <param name="posInUrl">The current pos in the url - this is needed to get the real parameter before splitting. Due to the split we lost the seperator char</param> private void AddNode(Dictionary <String, UrlNode> urlNodes, IEnumerable <String> urlParts, MethodInfo methodInfo, String url, Int32 posInUrl, Boolean?needsExplicitAuthentication) { var val = urlParts.FirstOrDefault(); if (val == null) { throw new ArgumentNullException("urlParts.First"); } #region SpeedUp by removing all between {...} if (val.StartsWith("{") && val.EndsWith("}")) // something like /{....} or .{....} or ?{.....} will be changed to /{} .{} ?{} { val = "{}"; } #endregion UrlNode curUrlNode = null; #region Use an existing node or add a new one if (urlNodes.ContainsKey(val)) { curUrlNode = urlNodes[val]; } else { curUrlNode = new UrlNode(); curUrlNode.NeedsExplicitAuthentication = needsExplicitAuthentication; urlNodes.Add(val, curUrlNode); } #endregion #region If there are some more parts proceed or set the methodInfo for the last part if (urlParts.CountIsGreater(1)) { // there are still some more parts of the URL AddNode(curUrlNode.ChildNodes, urlParts.Skip(1), methodInfo, url, posInUrl, needsExplicitAuthentication); } else { // this was the last one - take the methodInfo curUrlNode.Callback = methodInfo; } #endregion }
/// <summary> /// This will check /// </summary> /// <param name="urlNodes"></param> /// <param name="urlParts">the splittet</param> /// <param name="parameters">The parameters, parsed from the url</param> /// <param name="url">The uriginal url - this is needed to get the real parameter before splitting. Due to the split we lost the seperator char</param> /// <param name="posInUrl">The current pos in the url - this is needed to get the real parameter before splitting. Due to the split we lost the seperator char</param> /// <returns></returns> private Tuple <UrlNode, List <Object> > GetCallback(Dictionary <String, UrlNode> urlNodes, IEnumerable <String> urlParts, List <Object> parameters, String url, Int32 posInUrl) { var val = urlParts.FirstOrDefault(); if (val == null) { throw new ArgumentNullException("urlParts.First"); } val = val.ToLower(); UrlNode curUrlNode = null; if (urlNodes.ContainsKey(val)) { #region The current url node has this part of the URL curUrlNode = urlNodes[val]; posInUrl += (val.Length == 0) ? 1 : val.Length + 1; // for just a / (which is now a empty string because of the split) #endregion } else if (urlNodes.ContainsKey("{}")) { #region If there is a wildcard in this node, use this curUrlNode = urlNodes["{}"]; if (curUrlNode.ChildNodes.IsNullOrEmpty()) { // this is the last parameter - so add the rest of the url as well parameters.Add(url.Substring(posInUrl)); posInUrl = url.Length; return(new Tuple <UrlNode, List <object> >(curUrlNode, parameters)); } else { // just add this part and proceed if (url.Length > posInUrl) { //parameters.Add(url.Substring(posInUrl, (val.Length == 0) ? 1 : val.Length)); parameters.Add(url.Substring(posInUrl, val.Length)); posInUrl += val.Length + 1; // add 1 for the missing seperator char } else { parameters.Add(""); } } #endregion } else { #region The node does not have this part and a wildcard neither return(null); #endregion } if (urlParts.CountIsGreater(1) && !curUrlNode.ChildNodes.IsNullOrEmpty()) { #region There are more url parts AND childs in the current node // we have some more childs defined Tuple <UrlNode, List <object> > retval = null; var newParams = new List <Object>(); do { #region As long as we can go deeper lets do it retval = GetCallback(curUrlNode.ChildNodes, urlParts.Skip(1), newParams, url, posInUrl); if (retval == null) { #region There is no hit for the current nodes childs and the next url parts if (curUrlNode.ChildNodes.ContainsKey("{}")) { #region But the childs contains a wildcard we could use curUrlNode = curUrlNode.ChildNodes["{}"]; if (curUrlNode.ChildNodes.IsNullOrEmpty()) { #region The wildcard child has no more childs to verify, so lets take it parameters.Add(url.Substring(posInUrl)); retval = new Tuple <UrlNode, List <object> >(curUrlNode, newParams);//parameters); #endregion } else { #region The wildcard child have mor childs which needs to be verified urlParts = urlParts.Skip(1); if (GetCallback(curUrlNode.ChildNodes, urlParts.Skip(1), newParams, url, posInUrl) == null) { #region The next parts do not leed into a successfull mapping, lets use this wildcard parameters.Add(url.Substring(posInUrl)); retval = new Tuple <UrlNode, List <object> >(curUrlNode, parameters); parameters = null; #endregion } else { #region Take this wildcard as parameter and proceed val = urlParts.First(); newParams.Add(url.Substring(posInUrl, (val.Length == 0) ? 1 : val.Length)); posInUrl += (val.Length == 0) ? 1 : val.Length + 1; #endregion } #endregion } #endregion } else { #region This part is still not valid, return null to proceed with the predecessor level return(null); #endregion } #endregion } #endregion } while (retval == null); #region Are there any parameters to add to the result? if (!parameters.IsNullOrEmpty()) { #region We need to swap the parameters due to recursive call parameters.AddRange(retval.Item2); retval = new Tuple <UrlNode, List <object> >(retval.Item1, parameters); #endregion } #endregion return(retval); #endregion } else if (curUrlNode.Callback == null && !curUrlNode.ChildNodes.IsNullOrEmpty() && curUrlNode.ChildNodes.ContainsKey("{}")) { #region The current callback is null AND this is the last part of the url parameters.Add(url.Substring(posInUrl)); curUrlNode = curUrlNode.ChildNodes["{}"]; #endregion } else if (urlParts.CountIsGreater(1) && curUrlNode.ChildNodes.IsNullOrEmpty()) { #region No childs but still some url parts return(null); #endregion } else if (curUrlNode.Callback == null && !curUrlNode.ChildNodes.IsNullOrEmpty() && !curUrlNode.ChildNodes.ContainsKey("{}")) { #region There are childs but they have no placeholders ({}), so we have no valid definition return(null); #endregion } return(new Tuple <UrlNode, List <object> >(curUrlNode, parameters)); }
/// <summary> /// /// </summary> /// <param name="urlNodes"></param> /// <param name="urlParts"></param> /// <param name="methodInfo"></param> /// <param name="url">The uriginal url - this is needed to get the real parameter before splitting. Due to the split we lost the seperator char</param> /// <param name="posInUrl">The current pos in the url - this is needed to get the real parameter before splitting. Due to the split we lost the seperator char</param> private void AddNode(Dictionary<String, UrlNode> urlNodes, IEnumerable<String> urlParts, MethodInfo methodInfo, String url, Int32 posInUrl, Boolean? needsExplicitAuthentication) { var val = urlParts.FirstOrDefault(); if (val == null) { throw new ArgumentNullException("urlParts.First"); } #region SpeedUp by removing all between {...} if (val.StartsWith("{") && val.EndsWith("}")) // something like /{....} or .{....} or ?{.....} will be changed to /{} .{} ?{} { val = "{}"; } #endregion UrlNode curUrlNode = null; #region Use an existing node or add a new one if (urlNodes.ContainsKey(val)) { curUrlNode = urlNodes[val]; } else { curUrlNode = new UrlNode(); curUrlNode.NeedsExplicitAuthentication = needsExplicitAuthentication; urlNodes.Add(val, curUrlNode); } #endregion #region If there are some more parts proceed or set the methodInfo for the last part if (urlParts.CountIsGreater(1)) { // there are still some more parts of the URL AddNode(curUrlNode.ChildNodes, urlParts.Skip(1), methodInfo, url, posInUrl, needsExplicitAuthentication); } else { // this was the last one - take the methodInfo curUrlNode.Callback = methodInfo; } #endregion }