static void CacheBinaryReaderMethods() { var types = ExecutingAssembly.GetTypes(); // get BinaryReader extension methods from the executing assembly var extensionMethods = (from type in types where type.IsSealed && !type.IsGenericType && !type.IsNested from method in type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where method.IsDefined(typeof(ExtensionAttribute), false) where method.GetParameters()[0].ParameterType == typeof(BinaryReader) select new { method = method, type = method.ReturnType }).ToList(); // trim this down further to one of each return type extensionMethods = (from method in extensionMethods group method by method.type into g select g.First()).ToList(); using (var provider = new CSharpCodeProvider()) { var test = provider.CreateValidIdentifier(typeof(int).ToString()); var binaryReaderMethods = (from method in typeof(BinaryReader).GetMethods() where method.ReturnType != typeof(void) select new { method = method, type = method.ReturnType }).ToList().Where(x => { var typeString = provider.CreateValidIdentifier((x.type).ToString()); typeString = typeString.Split('.').Last(); return x.method.Name.ToLower().Contains(typeString.ToLower()); }).ToList(); binaryReaderMethods = (from method in binaryReaderMethods group method by method.type into g select g.First()).ToList(); var totalMethods = binaryReaderMethods.Union(extensionMethods); ReadTypeMethods = new Dictionary<Type, MethodInvoker>(totalMethods.Count()); foreach (var item in totalMethods) { ReadTypeMethods[item.type] = item.method.DelegateForCallMethod(); } } }
protected virtual string ValidateFieldName(string fieldName) { using (var provider = new CSharpCodeProvider()) { if (!provider.IsValidIdentifier(fieldName)) { var huh = provider.CreateValidIdentifier(fieldName); fieldName = string.Format("invalidName_{0}", fieldName); } } return fieldName; }
private static void ProcessSwaggerDocuments(string proxyOutputFile) { Console.WriteLine(); Console.WriteLine("Processing Swagger documents..."); PrintHeaders(); foreach (var swaggerDocDictionaryEntry in _swaggerDocDictionaryList.OrderBy(x => x.Key.Id)) { var endPoint = swaggerDocDictionaryEntry.Key; Console.WriteLine("Processing {0}", endPoint.Url); WriteLine(string.Format("// {0} Proxy", endPoint.Url)); string methodNameAppend = string.Empty; if (endPoint.AppendAsyncToMethodName) { methodNameAppend = "Async"; } var result = swaggerDocDictionaryEntry.Value; var parser = new SwaggerParser(); var proxyDefinition = parser.ParseSwaggerDoc(result, endPoint.ParseOperationIdForProxyName); WriteLine(string.Format("namespace {0} {{", endPoint.Namespace)); var proxies = proxyDefinition.Operations.Select(i => i.ProxyName).Distinct().ToList(); foreach (var proxy in proxies) { WriteLine( string.Format( "public interface {0}", string.Format("I{0}WebProxy", SwaggerParser.FixTypeName(proxy)))); WriteLine("{"); var proxy1 = proxy; foreach (var operationDef in proxyDefinition.Operations.Where(i => i.ProxyName.Equals(proxy1))) { string returnType = string.IsNullOrEmpty(operationDef.ReturnType) ? string.Empty : string.Format("<{0}>", operationDef.ReturnType); var enums = operationDef.Parameters.Where(i => i.Type.EnumValues != null); List<Enum> proxyParamEnums = new List<Enum>(); foreach (var enumParam in enums) { enumParam.Type.TypeName = operationDef.OperationId + enumParam.Type.Name; proxyParamEnums.Add( new Enum() { Name = enumParam.Type.TypeName, Values = enumParam.Type.EnumValues }); } var className = SwaggerParser.FixTypeName(proxy) + "WebProxy"; string parameters = string.Join( ", ", operationDef.Parameters.OrderByDescending(i => i.IsRequired) .Select( x => { // if parameter is enum include the namespace string parameter = x.Type.EnumValues != null ? string.Format("{0}.{1}.", endPoint.Namespace, className) : string.Empty; parameter += x.IsRequired == false ? string.Format( "{0} {1} = {3}{2}", GetDefaultType(x), x.Type.GetCleanTypeName(), GetDefaultValue(x), parameter) : string.Format("{0} {1}", GetDefaultType(x), x.Type.GetCleanTypeName()); return parameter; })); WriteLine( string.Format( "Task{0} {1}{2}({3});", returnType, SwaggerParser.FixTypeName(operationDef.OperationId), methodNameAppend, parameters)); } WriteLine("}"); } foreach (var proxy in proxies) { // start class defintion WriteLine("/// <summary>"); WriteLine(string.Format("/// Web Proxy for {0}", proxy)); WriteLine("/// </summary>"); var className = SwaggerParser.FixTypeName(proxy) + "WebProxy"; WriteLine( string.Format( "public class {0} : {1}, I{0}", className, endPoint.BaseProxyClass)); WriteLine("{"); WriteLine( string.Format( "public {0}{1}", className, endPoint.ProxyConstructorSuffix)); WriteLine("{}"); WriteLine(); List<Enum> proxyParamEnums = new List<Enum>(); WriteLine(@"// helper function for building uris."); WriteLine(@"private string AppendQuery(string currentUrl, string paramName, string value)"); WriteLine(@"{"); WriteLine(@"if (currentUrl.Contains(""?""))"); WriteLine(@"currentUrl += string.Format(""&{0}={1}"", paramName, Uri.EscapeUriString(value));"); WriteLine(@"else"); WriteLine(@"currentUrl += string.Format(""?{0}={1}"", paramName, Uri.EscapeUriString(value));"); WriteLine(@"return currentUrl;"); WriteLine(@"}"); WriteLine(); // Async operations (web methods) var proxy1 = proxy; foreach (var operationDef in proxyDefinition.Operations.Where(i => i.ProxyName.Equals(proxy1))) { string returnType = string.IsNullOrEmpty(operationDef.ReturnType) ? string.Empty : string.Format("<{0}>", operationDef.ReturnType); var enums = operationDef.Parameters.Where(i => i.Type.EnumValues != null); foreach (var enumParam in enums) { enumParam.Type.TypeName = operationDef.OperationId + enumParam.Type.Name; proxyParamEnums.Add( new Enum() { Name = enumParam.Type.TypeName, Values = enumParam.Type.EnumValues }); } string parameters = string.Join( ", ", operationDef.Parameters.OrderByDescending(i => i.IsRequired) .Select( x => (x.IsRequired == false) ? string.Format( "{0} {1} = {2}", GetDefaultType(x), x.Type.GetCleanTypeName(), GetDefaultValue(x)) : string.Format("{0} {1}", GetDefaultType(x), x.Type.GetCleanTypeName()))); WriteLine("/// <summary>"); var summary = (SecurityElement.Escape(operationDef.Description) ?? "").Replace("\n", "\n///"); if (string.IsNullOrWhiteSpace(summary)) { WriteLine("///"); } else { WriteLine(string.Format("/// {0}", summary)); } WriteLine("/// </summary>"); foreach (var parameter in operationDef.Parameters) { WriteLine( string.Format( "/// <param name=\"{0}\">{1}</param>", parameter.Type.Name, (SecurityElement.Escape(parameter.Description) ?? "").Replace("\n", "\n///"))); } WriteLine( string.Format( "public async Task{0} {1}{2}({3})", returnType, SwaggerParser.FixTypeName(operationDef.OperationId), methodNameAppend, parameters)); WriteLine("{"); if (operationDef.Path.StartsWith("/")) { WriteLine(string.Format("var url = \"{0}\"", operationDef.Path.Substring(1))); } else { WriteLine(string.Format("var url = \"{0}\"", operationDef.Path)); } foreach (var parameter in operationDef.Parameters.Where(i => i.ParameterIn == ParameterIn.Path)) { WriteLine(string.Format("\t.Replace(\"{{{0}}}\", {0}.ToString())", parameter.Type.GetCleanTypeName())); } WriteLine(";"); var queryParams = operationDef.Parameters.Where(i => i.ParameterIn == ParameterIn.Query).ToList(); if (queryParams.Count > 0) { foreach (var parameter in queryParams) { if (parameter.IsRequired == false && (parameter.Type.EnumValues == null || parameter.Type.EnumValues.Any() == false)) { WriteNullIfStatementOpening(parameter.Type.GetCleanTypeName(), parameter.Type.TypeName); } if (string.IsNullOrWhiteSpace(parameter.CollectionFormat) == false) { // array if (parameter.CollectionFormat.Equals("csv", StringComparison.OrdinalIgnoreCase)) { WriteLine( string.Format( "url = AppendQuery(url, \"{0}\", string.Join(\",\", {1}));", parameter.Type.Name, parameter.Type.GetCleanTypeName())); } else if (parameter.CollectionFormat.Equals("ssv", StringComparison.OrdinalIgnoreCase)) { WriteLine( string.Format( "url = AppendQuery(url, \"{0}\", string.Join(\" \", {1}));", parameter.Type.Name, parameter.Type.GetCleanTypeName())); } else if (parameter.CollectionFormat.Equals("tsv", StringComparison.OrdinalIgnoreCase)) { WriteLine( string.Format( "url = AppendQuery(url, \"{0}\", string.Join(\"\t\", {1}));", parameter.Type.Name, parameter.Type.GetCleanTypeName())); } else if (parameter.CollectionFormat.Equals("pipes", StringComparison.OrdinalIgnoreCase)) { WriteLine( string.Format( "url = AppendQuery(url, \"{0}\", string.Join(\"\t\", {1}));", parameter.Type.Name, parameter.Type.GetCleanTypeName())); } else if (parameter.CollectionFormat.Equals("multi", StringComparison.OrdinalIgnoreCase)) { WriteLine(string.Format("foreach(var item in {0})", parameter.Type.GetCleanTypeName())); WriteLine("{"); WriteLine( string.Format( "url = AppendQuery(url, \"{0}\", item.ToString());", parameter.Type.Name)); WriteLine("}"); } else { //Warning("unknown collection format found"); WriteLine( string.Format( "url = AppendQuery(url, \"{0}\", {1}.ToString());", parameter.Type.Name, parameter.Type.GetCleanTypeName())); } } else { WriteLine( string.Format( "url = AppendQuery(url, \"{0}\", {1}.ToString());", parameter.Type.Name, parameter.Type.GetCleanTypeName())); } if (parameter.IsRequired == false && (parameter.Type.EnumValues == null || parameter.Type.EnumValues.Any() == false)) { WriteLine("}"); } } } WriteLine(); WriteLine("using (var client = BuildHttpClient())"); WriteLine("{"); switch (operationDef.Method.ToUpperInvariant()) { case "GET": WriteLine("var response = await client.GetAsync(url).ConfigureAwait(false);"); break; case "DELETE": WriteLine("var response = await client.DeleteAsync(url).ConfigureAwait(false);"); break; case "PUT": var putBodyParam = operationDef.Parameters.FirstOrDefault( i => i.ParameterIn == ParameterIn.Body); if (putBodyParam != null) { WriteLine( string.Format( "var response = await client.PutAsJsonAsync(url, {0}).ConfigureAwait(false);", putBodyParam.Type.Name)); } else if (operationDef.Parameters.Any(i => i.ParameterIn == ParameterIn.FormData)) { var formData = operationDef.Parameters.Where(i => i.ParameterIn == ParameterIn.FormData).ToList(); WriteLine("var formKeyValuePairs = new List<KeyValuePair<string, string>>();"); foreach (var formParam in formData.Where(x => x.Type.TypeName != "file")) { if (formParam.IsRequired == false) { WriteNullIfStatementOpening(formParam.Type.Name, formParam.Type.TypeName); } WriteLine( string.Format( "formKeyValuePairs.Add(new KeyValuePair<string, string>(\"{0}\", {0}));", formParam.Type.Name)); if (formParam.IsRequired == false) { WriteLine("}"); } } foreach (var formParam in formData.Where(x => x.Type.TypeName == "file")) { WriteLine( string.Format( "var fileContent = new ByteArrayContent({0}.Item2);", formParam.Type.Name)); WriteLine( string.Format( "fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue(\"attachment\") {{ FileName = \"{0}.Item1\" }};", formParam.Type.Name)); } WriteLine("HttpContent content = new FormUrlEncodedContent(formKeyValuePairs);"); WriteLine("var response = await client.PutAsync(url, content).ConfigureAwait(false);"); } else { WriteLine( "var response = await client.PutAsync(url, new StringContent(string.Empty)).ConfigureAwait(false);"); } break; case "POST": var postBodyParam = operationDef.Parameters.FirstOrDefault(i => i.ParameterIn == ParameterIn.Body); if (postBodyParam != null) { WriteLine( string.Format( "var response = await client.PostAsJsonAsync(url, {0}).ConfigureAwait(false);", postBodyParam.Type.Name)); } else if (operationDef.Parameters.Any(i => i.ParameterIn == ParameterIn.FormData)) { var formData = operationDef.Parameters.Where(i => i.ParameterIn == ParameterIn.FormData).ToList(); WriteLine("var formKeyValuePairs = new List<KeyValuePair<string, string>>();"); foreach (var formParam in formData.Where(x => x.Type.TypeName != "file")) { if (formParam.IsRequired == false) { WriteNullIfStatementOpening(formParam.Type.Name, formParam.Type.TypeName); } WriteLine( string.Format( "formKeyValuePairs.Add(new KeyValuePair<string, string>(\"{0}\", {0}));", formParam.Type.Name)); if (formParam.IsRequired == false) { WriteLine("}"); } } foreach (var formParam in formData.Where(x => x.Type.TypeName == "file")) { WriteLine( string.Format( "var {0}Content = new ByteArrayContent({0}.Item2);", formParam.Type.Name)); WriteLine( string.Format( "{0}Content.Headers.ContentDisposition = new ContentDispositionHeaderValue(\"attachment\") {{ FileName = {0}.Item1 }};", formParam.Type.Name)); } WriteLine("HttpContent content = new FormUrlEncodedContent(formKeyValuePairs);"); WriteLine("var response = await client.PostAsync(url, content).ConfigureAwait(false);"); } else { WriteLine( "var response = await client.PostAsync(url, new StringContent(string.Empty)).ConfigureAwait(false);"); } break; } WriteLine("await EnsureSuccessStatusCodeAsync(response);"); if (string.IsNullOrWhiteSpace(operationDef.ReturnType) == false) { WriteLine( string.Format( "return await response.Content.ReadAsAsync<{0}>().ConfigureAwait(false);", operationDef.ReturnType)); } WriteLine("}"); // close up the using WriteLine("}"); // close up the method WriteLine(); } foreach (var proxyParamEnum in proxyParamEnums) { WriteLine(string.Format("public enum {0}", SwaggerParser.FixTypeName(proxyParamEnum.Name))); WriteLine("{"); foreach (var value in proxyParamEnum.Values.Distinct()) { WriteLine(string.Format("{0},", SwaggerParser.FixTypeName(value))); } WriteLine("}"); WriteLine(); } // close class def WriteLine("}"); WriteLine(); } // Model Classes foreach (var classDef in proxyDefinition.ClassDefinitions) { List<Enum> modelEnums = new List<Enum>(); WriteLine( string.Format( "public class {0}{1}", classDef.Name, string.IsNullOrEmpty(classDef.Inherits) ? string.Empty : string.Format(" : {0}", classDef.Inherits))); WriteLine("{"); foreach (var prop in classDef.Properties) { var typeName = string.IsNullOrWhiteSpace(prop.TypeName) ? "object" : prop.TypeName; WriteLine(string.Format("public {0} {1} {{ get; set; }}", typeName, prop.Name)); if (prop.EnumValues != null) { modelEnums.Add(new Enum() { Name = typeName, Values = prop.EnumValues }); } } foreach (var modelEnum in modelEnums) { var csharpCodeProvider = new CSharpCodeProvider(); WriteLine(string.Format("public enum {0}", csharpCodeProvider.CreateValidIdentifier(modelEnum.Name))); WriteLine("{"); foreach (var value in modelEnum.Values.Distinct()) { WriteLine(string.Format("{0},", SwaggerParser.FixTypeName(value))); } WriteLine("}"); WriteLine(); } WriteLine("}"); WriteLine(); } // close namespace def WriteLine("}"); File.WriteAllText(proxyOutputFile, FileText.ToString()); } }