Method GetMethod(HttpMethodAttribute attrib, MethodInfo methodInfo) { string actionTemplate = attrib.Template; if (string.IsNullOrEmpty(actionTemplate)) { actionTemplate = methodInfo.GetCustomAttribute <RouteAttribute>()?.Template; } Method method = convertMethod.Convert(methodInfo); if (!method.ReturnType.IsAsync) { method.ReturnType = DotNetType.MakeAsync(method.ReturnType); } method.Body = new CodeBlock(); StringBuilder sb = new StringBuilder(); using (StringWriter writer = new StringWriter(sb)) { writer.Write("string path = $\"{ControllerPath}"); if (!string.IsNullOrEmpty(actionTemplate)) { writer.Write("/"); writer.Write(actionTemplate); } writer.WriteLine("\";"); writer.WriteLine("var queryString = new System.Collections.Specialized.NameValueCollection();"); HashSet <string> actionRoutes = new HashSet <string>(); if (attrib.Template != null) { foreach (Match match in actionRouteRegex.Matches(attrib.Template)) { actionRoutes.Add(match.Groups[1].Value); } } ParameterInfo fromBody = null; foreach (var item in methodInfo.GetParameters()) { if (item.GetCustomAttribute <FromBodyAttribute>() != null) { fromBody = item; } else if (!actionRoutes.Contains(item.Name)) { writer.Write($"queryString.Add(nameof(@{item.Name}), "); if (item.ParameterType != typeof(string)) { writer.WriteLine($"System.Convert.ToString(@{item.Name}));"); } else { writer.WriteLine($"@{item.Name});"); } } } if (fromBody?.ParameterType == typeof(string)) { writer.WriteLine($"using (var request = this.CreateStringRequest({attrib.GetMethod()}, path, queryString, @{fromBody.Name})) {{"); } else if (fromBody == null) { writer.WriteLine($"using (var request = this.CreateRequest({attrib.GetMethod()}, path, queryString)) {{"); } else { writer.WriteLine($"using (var request = this.CreateJsonRequest<{new DotNetType(fromBody.ParameterType)}>({attrib.GetMethod()}, path, queryString, @{fromBody.Name})) {{"); } writer.Tab(); //skip "return" if return type is void or Task if (!method.ReturnType.IsVoid) { writer.Write("return "); } writer.Write($"await this.Invoke"); if (!method.ReturnType.IsVoid && method.ReturnType != new DotNetType(typeof(string))) { writer.Write($"<{method.ReturnType.RemoveAsync()}>"); } writer.WriteLine("(request);"); writer.Write("}"); } method.Body.Content = sb.ToString(); method.Async = true; return(method); }