diff --git a/Rest.Net.Example/Client.Static.cs b/Rest.Net.Example/Client.Static.cs new file mode 100644 index 0000000..dae3b15 --- /dev/null +++ b/Rest.Net.Example/Client.Static.cs @@ -0,0 +1,121 @@ +namespace MontoyaTech.Rest.Net.Example; + +using System; +using System.Net; +using System.Net.Http; +using Newtonsoft.Json; + +public class StaticClient +{ + public static string BaseUrl; + + public static CookieContainer CookieContainer; + + public static HttpClientHandler ClientHandler; + + public static HttpClient HttpClient; + + public static void Init(string baseUrl) + { + if (string.IsNullOrWhiteSpace(baseUrl)) + throw new ArgumentException("baseUrl must not be null or whitespace."); + + if (baseUrl.EndsWith('/')) + baseUrl = baseUrl.Substring(0, baseUrl.Length - 1); + + StaticClient.BaseUrl = baseUrl; + + StaticClient.CookieContainer = new CookieContainer(); + + StaticClient.ClientHandler = new HttpClientHandler() + { + AllowAutoRedirect = true, + UseCookies = true, + CookieContainer = StaticClient.CookieContainer, + AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate + }; + + StaticClient.HttpClient = new HttpClient(StaticClient.ClientHandler); + + StaticClient.HttpClient.DefaultRequestHeaders.Add("Accept", "*/*"); + + StaticClient.HttpClient.DefaultRequestHeaders.Add("Connection", "keep-alive"); + + StaticClient.HttpClient.DefaultRequestHeaders.Add("Accept-Encoding", "identity"); + } + + public class Test + { + public static string Status() + { + var message = new HttpRequestMessage(HttpMethod.Get, $"{StaticClient.BaseUrl}/status"); + + var response = StaticClient.HttpClient.Send(message); + + if (response.StatusCode == HttpStatusCode.OK) + return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().GetAwaiter().GetResult()); + else + throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); + } + + public static string Add(double a, double b) + { + var message = new HttpRequestMessage(HttpMethod.Post, $"{StaticClient.BaseUrl}/add/{a}/{b}"); + + var response = StaticClient.HttpClient.Send(message); + + if (response.StatusCode == HttpStatusCode.OK) + return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().GetAwaiter().GetResult()); + else + throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); + } + } + + public class Auth + { + public static bool UserExists(string name) + { + var message = new HttpRequestMessage(HttpMethod.Get, $"{StaticClient.BaseUrl}/auth/{name}"); + + var response = StaticClient.HttpClient.Send(message); + + if (response.StatusCode == HttpStatusCode.OK) + return bool.Parse(response.Content.ReadAsStringAsync().GetAwaiter().GetResult()); + else + throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); + } + + public static void Signup(User request) + { + var message = new HttpRequestMessage(HttpMethod.Post, $"{StaticClient.BaseUrl}/auth/signup"); + + message.Content = new StringContent(JsonConvert.SerializeObject(request)); + + var response = StaticClient.HttpClient.Send(message); + + if (response.StatusCode != HttpStatusCode.OK) + throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); + } + + public static User Get() + { + var message = new HttpRequestMessage(HttpMethod.Get, $"{StaticClient.BaseUrl}/auth"); + + var response = StaticClient.HttpClient.Send(message); + + if (response.StatusCode == HttpStatusCode.OK) + return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().GetAwaiter().GetResult()); + else + throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); + } + } + + public class User + { + public string Name; + + public System.Collections.Generic.List List; + + public ulong Property { get; set; } + } +} \ No newline at end of file diff --git a/Rest.Net.Example/Client.cs b/Rest.Net.Example/Client.cs index 485e840..f7d24e1 100644 --- a/Rest.Net.Example/Client.cs +++ b/Rest.Net.Example/Client.cs @@ -1,123 +1,143 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace MontoyaTech.Rest.Net.Example; -namespace MontoyaTech.Rest.Net.Example +using System; +using System.Net; +using System.Net.Http; +using Newtonsoft.Json; + +public class Client { - using System; - using System.Net.Http; - using Newtonsoft.Json; + public string BaseUrl; - public class Client + public CookieContainer CookieContainer; + + public HttpClientHandler ClientHandler; + + public HttpClient HttpClient; + + public TestApi Test; + + public AuthApi Auth; + + public Client(string baseUrl) { - public string BaseUrl; + if (string.IsNullOrWhiteSpace(baseUrl)) + throw new ArgumentException("baseUrl must not be null or whitespace."); - public HttpClient HttpClient; + if (baseUrl.EndsWith('/')) + baseUrl = baseUrl.Substring(0, baseUrl.Length - 1); - public TestApi Test; + this.BaseUrl = baseUrl; - public AuthApi Auth; + this.CookieContainer = new CookieContainer(); - public Client(string baseUrl) + this.ClientHandler = new HttpClientHandler() { - this.BaseUrl = baseUrl; - this.Test = new TestApi(this); - this.Auth = new AuthApi(this); - this.HttpClient = new HttpClient(); - this.HttpClient.DefaultRequestHeaders.Add("Accept", "*/*"); - this.HttpClient.DefaultRequestHeaders.Add("Connection", "keep-alive"); - this.HttpClient.DefaultRequestHeaders.Add("Accept-Encoding", "identity"); + AllowAutoRedirect = true, + UseCookies = true, + CookieContainer = this.CookieContainer, + AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate + }; + + this.HttpClient = new HttpClient(this.ClientHandler); + + this.HttpClient.DefaultRequestHeaders.Add("Accept", "*/*"); + + this.HttpClient.DefaultRequestHeaders.Add("Connection", "keep-alive"); + + this.HttpClient.DefaultRequestHeaders.Add("Accept-Encoding", "identity"); + + this.Test = new TestApi(this); + + this.Auth = new AuthApi(this); + } + + public class TestApi + { + public Client Client; + + public TestApi(Client client) + { + this.Client = client; } - public class TestApi + public string Status() { - public Client Client; + var message = new HttpRequestMessage(HttpMethod.Get, $"{this.Client.BaseUrl}/status"); - public TestApi(Client client) - { - this.Client = client; - } + var response = this.Client.HttpClient.Send(message); - public string Status() - { - var message = new HttpRequestMessage(HttpMethod.Get, $"{this.Client.BaseUrl}/status"); - - var response = this.Client.HttpClient.Send(message); - - if (response.StatusCode == System.Net.HttpStatusCode.OK) - return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().GetAwaiter().GetResult()); - else - throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); - } - - public string Add(double a, double b) - { - var message = new HttpRequestMessage(HttpMethod.Post, $"{this.Client.BaseUrl}/add/{a}/{b}"); - - var response = this.Client.HttpClient.Send(message); - - if (response.StatusCode == System.Net.HttpStatusCode.OK) - return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().GetAwaiter().GetResult()); - else - throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); - } + if (response.StatusCode == HttpStatusCode.OK) + return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().GetAwaiter().GetResult()); + else + throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); } - public class AuthApi + public string Add(double a, double b) { - public Client Client; + var message = new HttpRequestMessage(HttpMethod.Post, $"{this.Client.BaseUrl}/add/{a}/{b}"); - public AuthApi(Client client) - { - this.Client = client; - } + var response = this.Client.HttpClient.Send(message); - public bool UserExists(string name) - { - var message = new HttpRequestMessage(HttpMethod.Get, $"{this.Client.BaseUrl}/auth/{name}"); - - var response = this.Client.HttpClient.Send(message); - - if (response.StatusCode == System.Net.HttpStatusCode.OK) - return bool.Parse(response.Content.ReadAsStringAsync().GetAwaiter().GetResult()); - else - throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); - } - - public void Signup(User request) - { - var message = new HttpRequestMessage(HttpMethod.Post, $"{this.Client.BaseUrl}/auth/signup"); - - message.Content = new StringContent(JsonConvert.SerializeObject(request)); - - var response = this.Client.HttpClient.Send(message); - - if (response.StatusCode == System.Net.HttpStatusCode.OK) - throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); - } - - public User Get() - { - var message = new HttpRequestMessage(HttpMethod.Get, $"{this.Client.BaseUrl}/auth"); - - var response = this.Client.HttpClient.Send(message); - - if (response.StatusCode == System.Net.HttpStatusCode.OK) - return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().GetAwaiter().GetResult()); - else - throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); - } - } - - public class User - { - public string Name; - - public System.Collections.Generic.List List; - - public ulong Property { get; set; } + if (response.StatusCode == HttpStatusCode.OK) + return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().GetAwaiter().GetResult()); + else + throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); } } -} + + public class AuthApi + { + public Client Client; + + public AuthApi(Client client) + { + this.Client = client; + } + + public bool UserExists(string name) + { + var message = new HttpRequestMessage(HttpMethod.Get, $"{this.Client.BaseUrl}/auth/{name}"); + + var response = this.Client.HttpClient.Send(message); + + if (response.StatusCode == HttpStatusCode.OK) + return bool.Parse(response.Content.ReadAsStringAsync().GetAwaiter().GetResult()); + else + throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); + } + + public void Signup(User request) + { + var message = new HttpRequestMessage(HttpMethod.Post, $"{this.Client.BaseUrl}/auth/signup"); + + message.Content = new StringContent(JsonConvert.SerializeObject(request)); + + var response = this.Client.HttpClient.Send(message); + + if (response.StatusCode != HttpStatusCode.OK) + throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); + } + + public User Get() + { + var message = new HttpRequestMessage(HttpMethod.Get, $"{this.Client.BaseUrl}/auth"); + + var response = this.Client.HttpClient.Send(message); + + if (response.StatusCode == HttpStatusCode.OK) + return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().GetAwaiter().GetResult()); + else + throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); + } + } + + public class User + { + public string Name; + + public System.Collections.Generic.List List; + + public ulong Property { get; set; } + } +} \ No newline at end of file diff --git a/Rest.Net.Example/Program.cs b/Rest.Net.Example/Program.cs index 181aca9..20d5087 100644 --- a/Rest.Net.Example/Program.cs +++ b/Rest.Net.Example/Program.cs @@ -40,6 +40,11 @@ namespace MontoyaTech.Rest.Net.Example string code = listener.GenerateCSharpClient(); Console.WriteLine(code); + Console.WriteLine(); + + string staticCode = listener.GenerateCSharpClient("StaticClient", staticCode: true); + + Console.WriteLine(staticCode); listener.RequestPreProcessEvent += (HttpListenerContext context) => { Console.WriteLine($"[{context.Request.HttpMethod}] Request start: " + context.Request.RawUrl); @@ -64,6 +69,10 @@ namespace MontoyaTech.Rest.Net.Example var result = client.Auth.Get(); + StaticClient.Init(listener.BaseUrl); + + var result2 = StaticClient.Auth.Get(); + listener.Block(); } diff --git a/Rest.Net/Rest.Net.csproj b/Rest.Net/Rest.Net.csproj index 768c382..521ee13 100644 --- a/Rest.Net/Rest.Net.csproj +++ b/Rest.Net/Rest.Net.csproj @@ -17,7 +17,7 @@ MontoyaTech.Rest.Net MontoyaTech.Rest.Net True - 1.2.6 + 1.2.7 Logo_Symbol_Black_Outline.png diff --git a/Rest.Net/RestCSharpClientGenerator.cs b/Rest.Net/RestCSharpClientGenerator.cs index af727e7..e8752b1 100644 --- a/Rest.Net/RestCSharpClientGenerator.cs +++ b/Rest.Net/RestCSharpClientGenerator.cs @@ -46,16 +46,31 @@ namespace MontoyaTech.Rest.Net var writer = new CodeWriter(); writer.WriteLine("using System;"); + writer.WriteLine("using System.Net;"); writer.WriteLine("using System.Net.Http;"); writer.WriteLine("using Newtonsoft.Json;"); writer.WriteBreak().WriteLine($"public class {this.ClientName}").WriteLine("{").Indent(); + //Create the base url field if (this.StaticCode) writer.WriteBreak().WriteLine("public static string BaseUrl;"); else writer.WriteBreak().WriteLine("public string BaseUrl;"); + //Create the cookie container field + if (this.StaticCode) + writer.WriteBreak().WriteLine("public static CookieContainer CookieContainer;"); + else + writer.WriteBreak().WriteLine("public CookieContainer CookieContainer;"); + + //Create the client handler field + if (this.StaticCode) + writer.WriteBreak().WriteLine("public static HttpClientHandler ClientHandler;"); + else + writer.WriteBreak().WriteLine("public HttpClientHandler ClientHandler;"); + + //Create the http client field if (this.StaticCode) writer.WriteBreak().WriteLine("public static HttpClient HttpClient;"); else @@ -71,14 +86,34 @@ namespace MontoyaTech.Rest.Net { writer.WriteBreak().WriteLine("public static void Init(string baseUrl)").WriteLine("{").Indent(); + //Make sure the base url isn't null or whitespace + writer.WriteBreak().WriteLine("if (string.IsNullOrWhiteSpace(baseUrl))"); + writer.Indent().WriteLine(@"throw new ArgumentException(""baseUrl must not be null or whitespace."");").Outdent(); + + //If the baseUrl ends with a /, remove it. + writer.WriteBreak().WriteLine("if (baseUrl.EndsWith('/'))"); + writer.Indent().WriteLine("baseUrl = baseUrl.Substring(0, baseUrl.Length - 1);").Outdent(); + //Init the base url - writer.WriteLine($"{this.ClientName}.BaseUrl = baseUrl;"); + writer.WriteBreak().WriteLine($"{this.ClientName}.BaseUrl = baseUrl;"); + + //Init the cookie container + writer.WriteBreak().WriteLine($"{this.ClientName}.CookieContainer = new CookieContainer();"); + + //Init the client handler + writer.WriteBreak().WriteLine($"{this.ClientName}.ClientHandler = new HttpClientHandler()"); + writer.WriteLine("{").Indent(); + writer.WriteLine("AllowAutoRedirect = true,"); + writer.WriteLine("UseCookies = true,"); + writer.WriteLine($"CookieContainer = {this.ClientName}.CookieContainer,"); + writer.WriteLine("AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate"); + writer.Outdent().WriteLine("};"); //Init the http client - writer.WriteLine($"{this.ClientName}.HttpClient = new HttpClient();"); - writer.WriteLine(@$"{this.ClientName}.HttpClient.DefaultRequestHeaders.Add(""Accept"", ""*/*"");"); - writer.WriteLine(@$"{this.ClientName}.HttpClient.DefaultRequestHeaders.Add(""Connection"", ""keep-alive"");"); - writer.WriteLine(@$"{this.ClientName}.HttpClient.DefaultRequestHeaders.Add(""Accept-Encoding"", ""identity"");"); + writer.WriteBreak().WriteLine($"{this.ClientName}.HttpClient = new HttpClient({this.ClientName}.ClientHandler);"); + writer.WriteBreak().WriteLine(@$"{this.ClientName}.HttpClient.DefaultRequestHeaders.Add(""Accept"", ""*/*"");"); + writer.WriteBreak().WriteLine(@$"{this.ClientName}.HttpClient.DefaultRequestHeaders.Add(""Connection"", ""keep-alive"");"); + writer.WriteBreak().WriteLine(@$"{this.ClientName}.HttpClient.DefaultRequestHeaders.Add(""Accept-Encoding"", ""identity"");"); writer.Outdent().WriteLine("}"); } @@ -86,18 +121,38 @@ namespace MontoyaTech.Rest.Net { writer.WriteBreak().WriteLine("public Client(string baseUrl)").WriteLine("{").Indent(); + //Make sure the base url isn't null or whitespace + writer.WriteBreak().WriteLine("if (string.IsNullOrWhiteSpace(baseUrl))"); + writer.Indent().WriteLine(@"throw new ArgumentException(""baseUrl must not be null or whitespace."");").Outdent(); + + //If the baseUrl ends with a /, remove it. + writer.WriteBreak().WriteLine("if (baseUrl.EndsWith('/'))"); + writer.Indent().WriteLine("baseUrl = baseUrl.Substring(0, baseUrl.Length - 1);").Outdent(); + //Init the base url - writer.WriteLine("this.BaseUrl = baseUrl;"); + writer.WriteBreak().WriteLine("this.BaseUrl = baseUrl;"); + + //Init the cookie container + writer.WriteBreak().WriteLine("this.CookieContainer = new CookieContainer();"); + + //Init the client handler + writer.WriteBreak().WriteLine("this.ClientHandler = new HttpClientHandler()"); + writer.WriteLine("{").Indent(); + writer.WriteLine("AllowAutoRedirect = true,"); + writer.WriteLine("UseCookies = true,"); + writer.WriteLine("CookieContainer = this.CookieContainer,"); + writer.WriteLine("AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate"); + writer.Outdent().WriteLine("};"); + + //Init the http client + writer.WriteBreak().WriteLine("this.HttpClient = new HttpClient(this.ClientHandler);"); + writer.WriteBreak().WriteLine(@"this.HttpClient.DefaultRequestHeaders.Add(""Accept"", ""*/*"");"); + writer.WriteBreak().WriteLine(@"this.HttpClient.DefaultRequestHeaders.Add(""Connection"", ""keep-alive"");"); + writer.WriteBreak().WriteLine(@"this.HttpClient.DefaultRequestHeaders.Add(""Accept-Encoding"", ""identity"");"); //Init all the route group fields foreach (var group in routeGroups) - writer.WriteLine($"this.{group.Key} = new {group.Key}Api(this);"); - - //Init the http client - writer.WriteLine("this.HttpClient = new HttpClient();"); - writer.WriteLine(@"this.HttpClient.DefaultRequestHeaders.Add(""Accept"", ""*/*"");"); - writer.WriteLine(@"this.HttpClient.DefaultRequestHeaders.Add(""Connection"", ""keep-alive"");"); - writer.WriteLine(@"this.HttpClient.DefaultRequestHeaders.Add(""Accept-Encoding"", ""identity"");"); + writer.WriteBreak().WriteLine($"this.{group.Key} = new {group.Key}Api(this);"); writer.Outdent().WriteLine("}"); } @@ -301,7 +356,7 @@ namespace MontoyaTech.Rest.Net } if (this.StaticCode) - writer.WriteSeparator().Write('$').Write('"').Write("{Client.BaseUrl}"); + writer.WriteSeparator().Write('$').Write('"').Write($"{{{this.ClientName}.BaseUrl}}"); else writer.WriteSeparator().Write('$').Write('"').Write("{this.Client.BaseUrl}"); @@ -346,14 +401,14 @@ namespace MontoyaTech.Rest.Net //Generate the response code if (this.StaticCode) - writer.WriteBreak().WriteLine("var response = Client.HttpClient.Send(message);"); + writer.WriteBreak().WriteLine($"var response = {this.ClientName}.HttpClient.Send(message);"); else writer.WriteBreak().WriteLine("var response = this.Client.HttpClient.Send(message);"); //Handle the response if (routeResponse != null) { - writer.WriteBreak().WriteLine("if (response.StatusCode == System.Net.HttpStatusCode.OK)").Indent(); + writer.WriteBreak().WriteLine("if (response.StatusCode == HttpStatusCode.OK)").Indent(); if (routeResponse.Json) { @@ -433,7 +488,7 @@ namespace MontoyaTech.Rest.Net } else { - writer.WriteBreak().WriteLine("if (response.StatusCode != System.Net.HttpStatusCode.OK)").Indent(); + writer.WriteBreak().WriteLine("if (response.StatusCode != HttpStatusCode.OK)").Indent(); writer.WriteLine(@"throw new Exception(""Unexpected Http Response StatusCode:"" + response.StatusCode);").Outdent(); }