/// <summary> /// 匹配Host /// </summary> /// <param name="route">路由条目</param> /// <param name="request">请求</param> private static void BindHostParameters(Route route, Request request) { MatchToKeys(route, request, route.Compiled.HostRegex.Match(request.RouteUri.Host)); }
/// <summary> /// 编译参数 /// </summary> /// <param name="route">路由条目</param> /// <param name="uri">uri</param> /// <param name="isHost">是否是host</param> /// <returns>编译数据</returns> private static Hashtable CompilePattern(Route route, string uri, bool isHost) { int[] parametersIndex = null; var defaultSeparator = isHost ? "." : "/"; //可选参数 var optionalParameters = new List <string>(MatchParameters(route.Uri.FullPath, @"\{(\w+?)\?\}", ref parametersIndex)); //所有参数 var parameters = MatchParameters(uri, @"\{(\w+?)\}", ref parametersIndex); //已经被使用的变量名 var variables = new List <string>(); var tokens = new List <string[]>(); var pos = 0; string varName, precedingText, precedingChar, where, followingPattern, nextSeparator; bool isSeparator; for (var i = 0; i < parameters.Length; i++) { varName = parameters[i]; // 获取当前匹配的变量之前的静态文本 precedingText = uri.Substring(pos, parametersIndex[i] - pos); pos = parametersIndex[i] + parameters[i].Length + 2; precedingChar = precedingText.Length <= 0 ? string.Empty : precedingText.Substring(precedingText.Length - 1); isSeparator = string.Empty != precedingChar && SEPARATORS.Contains(precedingChar); if (IsMatch(@"^\d", varName)) { throw new DomainException(string.Format("variable name {0} cannot start with a digit in route pattern {1}. please use a different name.", varName, uri)); } if (variables.Contains(varName)) { throw new DomainException(string.Format("route pattern {0} cannot reference variable name {1} more than once.", varName, uri)); } if (varName.Length > VARIABLE_MAXIMUM_LENGTH) { throw new DomainException(string.Format("variable name {0} cannot be longer than {1} characters in route pattern {2}. please use a shorter name.", varName, VARIABLE_MAXIMUM_LENGTH, uri)); } if (isSeparator && precedingText != precedingChar) { tokens.Add(new[] { "text", precedingText.Substring(0, precedingText.Length - precedingChar.Length) }); } else if (!isSeparator && precedingText.Length > 0) { tokens.Add(new[] { "text", precedingText }); } //获取where的约束条件 where = route.GetWhere(varName); if (where == null) { //获取之后的内容 followingPattern = uri.Substring(pos); //下一个分隔符 nextSeparator = FindNextSeparator(followingPattern); where = string.Format( "[^{0}{1}]+", RegexQuote(defaultSeparator), defaultSeparator != nextSeparator && nextSeparator != string.Empty ? RegexQuote(nextSeparator) : string.Empty ); } tokens.Add(new[] { "variable", isSeparator ? precedingChar : string.Empty, where, varName }); variables.Add(varName); } //如果不是全部内容则追加入后续内容 if (pos < uri.Length) { tokens.Add(new[] { "text", uri.Substring(pos) }); } var firstOptional = int.MaxValue; if (!isHost) { string[] token; for (var i = tokens.Count - 1; i >= 0; --i) { token = tokens[i]; if ("variable" == token[0] && optionalParameters.Contains(token[3])) { firstOptional = i; } else { break; } } } //计算并生成最终的表达式 var regexp = string.Empty; for (int i = 0, nbToken = tokens.Count; i < nbToken; ++i) { regexp += ComputeRegexp(tokens, i, firstOptional); } regexp = '^' + regexp + "$"; var hash = new Hashtable { { "staticPrefix", "text" == tokens[0][0] ? tokens[0][1] : string.Empty }, { "regex", regexp }, { "variables", variables.ToArray() } }; tokens.Reverse(); hash.Add("tokens", tokens.ToArray()); return(hash); }
/// <summary> /// 匹配路径 /// </summary> /// <param name="route">路由条目</param> /// <param name="request">请求</param> private static void BindPathParameters(Route route, Request request) { MatchToKeys(route, request, route.Compiled.RouteRegex.Match(request.RouteUri.NoParamFullPath)); }