From cf477522c03548c5c45f8bb104af52b8b9a7373c Mon Sep 17 00:00:00 2001 From: MattMo Date: Fri, 31 Mar 2023 08:21:32 -0700 Subject: [PATCH] Bumped package version to 1.4.7. Added support for Stream requests and MemoryStream responses. --- Rest.Net.Example/Client.Static.cs | 49 +++++++++- Rest.Net.Example/Client.cs | 60 +++++++++++- Rest.Net.Example/Program.cs | 40 +++++++- Rest.Net/Rest.Net.csproj | 2 +- Rest.Net/RestCSharpClientGenerator.cs | 135 +++++++++++++++----------- 5 files changed, 221 insertions(+), 65 deletions(-) diff --git a/Rest.Net.Example/Client.Static.cs b/Rest.Net.Example/Client.Static.cs index fe0d38c..bf61b42 100644 --- a/Rest.Net.Example/Client.Static.cs +++ b/Rest.Net.Example/Client.Static.cs @@ -152,7 +152,7 @@ public class StaticClient } } - public static void Signup(User request) + public static void Signup(UserDto request) { var message = new HttpRequestMessage(HttpMethod.Post, $"{StaticClient.BaseUrl}/auth/signup"); @@ -164,7 +164,7 @@ public class StaticClient throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); } - public static User Get() + public static UserDto Get() { var message = new HttpRequestMessage(HttpMethod.Get, $"{StaticClient.BaseUrl}/auth"); @@ -177,7 +177,7 @@ public class StaticClient if (string.IsNullOrEmpty(content)) return default; - return JsonConvert.DeserializeObject(content); + return JsonConvert.DeserializeObject(content); } else { @@ -207,13 +207,54 @@ public class StaticClient } } + public class Stream + { + public static void Upload(System.IO.MemoryStream request) + { + var message = new HttpRequestMessage(HttpMethod.Post, $"{StaticClient.BaseUrl}/upload"); + + request.Seek(0, System.IO.SeekOrigin.Begin); + + message.Content = new StreamContent(request); + + var response = StaticClient.HttpClient.Send(message); + + if (!response.IsSuccessStatusCode) + throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); + } + + public static System.IO.MemoryStream Download() + { + var message = new HttpRequestMessage(HttpMethod.Get, $"{StaticClient.BaseUrl}/download"); + + var response = StaticClient.HttpClient.Send(message); + + if (response.IsSuccessStatusCode) + { + var stream = new System.IO.MemoryStream(); + + response.Content.ReadAsStream().CopyTo(stream); + + stream.Seek(0, System.IO.SeekOrigin.Begin); + + return stream; + } + else + { + throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); + } + } + } + public class IncludedType { public int Test; } - public class User : BaseUser + public class UserDto : BaseUser { + public System.PlatformID MachineType; + public string Name; public System.Collections.Generic.List List; diff --git a/Rest.Net.Example/Client.cs b/Rest.Net.Example/Client.cs index ecc88ef..c7f3308 100644 --- a/Rest.Net.Example/Client.cs +++ b/Rest.Net.Example/Client.cs @@ -17,6 +17,8 @@ public class Client public AuthApi Auth; + public StreamApi Stream; + public Client(string baseUrl) { if (string.IsNullOrWhiteSpace(baseUrl)) @@ -48,6 +50,8 @@ public class Client this.Test = new TestApi(this); this.Auth = new AuthApi(this); + + this.Stream = new StreamApi(this); } public class TestApi @@ -174,7 +178,7 @@ public class Client } } - public void Signup(User request) + public void Signup(UserDto request) { var message = new HttpRequestMessage(HttpMethod.Post, $"{this.Client.BaseUrl}/auth/signup"); @@ -186,7 +190,7 @@ public class Client throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); } - public User Get() + public UserDto Get() { var message = new HttpRequestMessage(HttpMethod.Get, $"{this.Client.BaseUrl}/auth"); @@ -199,7 +203,7 @@ public class Client if (string.IsNullOrEmpty(content)) return default; - return JsonConvert.DeserializeObject(content); + return JsonConvert.DeserializeObject(content); } else { @@ -229,13 +233,61 @@ public class Client } } + public class StreamApi + { + public Client Client; + + public StreamApi(Client client) + { + this.Client = client; + } + + public void Upload(System.IO.MemoryStream request) + { + var message = new HttpRequestMessage(HttpMethod.Post, $"{this.Client.BaseUrl}/upload"); + + request.Seek(0, System.IO.SeekOrigin.Begin); + + message.Content = new StreamContent(request); + + var response = this.Client.HttpClient.Send(message); + + if (!response.IsSuccessStatusCode) + throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); + } + + public System.IO.MemoryStream Download() + { + var message = new HttpRequestMessage(HttpMethod.Get, $"{this.Client.BaseUrl}/download"); + + var response = this.Client.HttpClient.Send(message); + + if (response.IsSuccessStatusCode) + { + var stream = new System.IO.MemoryStream(); + + response.Content.ReadAsStream().CopyTo(stream); + + stream.Seek(0, System.IO.SeekOrigin.Begin); + + return stream; + } + else + { + throw new Exception("Unexpected Http Response StatusCode:" + response.StatusCode); + } + } + } + public class IncludedType { public int Test; } - public class User : BaseUser + public class UserDto : BaseUser { + public System.PlatformID MachineType; + public string Name; public System.Collections.Generic.List List; diff --git a/Rest.Net.Example/Program.cs b/Rest.Net.Example/Program.cs index 67754f1..a2aa529 100644 --- a/Rest.Net.Example/Program.cs +++ b/Rest.Net.Example/Program.cs @@ -75,7 +75,9 @@ namespace MontoyaTech.Rest.Net.Example new Route(HttpRequestMethod.Get, "/auth/{username}", Exists), new Route(HttpRequestMethod.Post, "/auth/signup", Signup), new Route(HttpRequestMethod.Get, "/auth/", Json), - new Route(HttpRequestMethod.Get, "/auth/role", GetRole) + new Route(HttpRequestMethod.Get, "/auth/role", GetRole), + new Route(HttpRequestMethod.Post, "/upload", Upload), + new Route(HttpRequestMethod.Get, "/download", Download) ); string code = listener.GenerateCSharpClient(); @@ -110,6 +112,24 @@ namespace MontoyaTech.Rest.Net.Example Console.WriteLine($"Rest api server running at {listener.BaseUrl}"); + StaticClient.Init(listener.BaseUrl); + + using (var stream = new MemoryStream()) + { + var bytes = Encoding.UTF8.GetBytes("hello world!"); + + stream.Write(bytes, 0, bytes.Length); + + StaticClient.Stream.Upload(stream); + } + + using (var stream = StaticClient.Stream.Download()) + { + var str = Encoding.UTF8.GetString(stream.ToArray()); + + Console.WriteLine("Download output:" + str); + } + listener.Block(); } @@ -182,5 +202,23 @@ namespace MontoyaTech.Rest.Net.Example { return context.Response.WithStatus(HttpStatusCode.OK).WithJson(new User("Rest.Net")); } + + [RouteGroup("Stream")] + [RouteRequest(typeof(MemoryStream))] + public static HttpListenerResponse Upload(HttpListenerContext context) + { + var content = context.Request.ReadAsString(); + + Console.WriteLine("Uploaded:" + content); + + return context.Response.WithStatus(HttpStatusCode.OK); + } + + [RouteGroup("Stream")] + [RouteResponse(typeof(MemoryStream))] + public static HttpListenerResponse Download(HttpListenerContext context) + { + return context.Response.WithStatus(HttpStatusCode.OK).WithText("Hello world"); + } } } diff --git a/Rest.Net/Rest.Net.csproj b/Rest.Net/Rest.Net.csproj index b8249b8..a6d07c4 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.4.6 + 1.4.7 Logo_Symbol_Black_Outline.png diff --git a/Rest.Net/RestCSharpClientGenerator.cs b/Rest.Net/RestCSharpClientGenerator.cs index 4393458..a89631a 100644 --- a/Rest.Net/RestCSharpClientGenerator.cs +++ b/Rest.Net/RestCSharpClientGenerator.cs @@ -3,8 +3,10 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; +using System.IO; using System.Threading.Tasks; using System.Xml.Linq; +using System.IO.Pipes; namespace MontoyaTech.Rest.Net { @@ -413,10 +415,20 @@ namespace MontoyaTech.Rest.Net //Add the request content if any. if (routeRequest != null) { - if (routeRequest.Json) + if (routeRequest.RequestType.IsAssignableTo(typeof(Stream))) + { + writer.WriteBreak().WriteLine("request.Seek(0, System.IO.SeekOrigin.Begin);"); + + writer.WriteBreak().WriteLine("message.Content = new StreamContent(request);"); + } + else if (routeRequest.Json) + { writer.WriteBreak().WriteLine("message.Content = new StringContent(JsonConvert.SerializeObject(request));"); + } else + { writer.WriteBreak().WriteLine("message.Content = new StringContent(request.ToString());"); + } } //Generate the response code @@ -430,80 +442,93 @@ namespace MontoyaTech.Rest.Net { writer.WriteBreak().WriteLine("if (response.IsSuccessStatusCode)").WriteLine("{").Indent(); - writer.WriteBreak().WriteLine("var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();"); - - writer.WriteBreak().WriteLine("if (string.IsNullOrEmpty(content))").Indent().WriteLine("return default;").Outdent(); - - if (routeResponse.Json) + if (routeResponse.ResponseType.IsEquivalentTo(typeof(MemoryStream))) { - writer.WriteBreak().WriteLine($"return JsonConvert.DeserializeObject<{this.GetTypeFullyResolvedName(routeResponse.ResponseType)}>(content);"); + writer.WriteBreak().WriteLine($"var stream = new {this.GetTypeFullyResolvedName(routeResponse.ResponseType)}();"); + + writer.WriteBreak().WriteLine("response.Content.ReadAsStream().CopyTo(stream);"); + + writer.WriteBreak().WriteLine("stream.Seek(0, System.IO.SeekOrigin.Begin);"); + + writer.WriteBreak().WriteLine("return stream;"); } else { - switch (Type.GetTypeCode(routeResponse.ResponseType)) + writer.WriteBreak().WriteLine("var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();"); + + writer.WriteBreak().WriteLine("if (string.IsNullOrEmpty(content))").Indent().WriteLine("return default;").Outdent(); + + if (routeResponse.Json) { - case TypeCode.Boolean: - writer.WriteBreak().WriteLine("return bool.Parse(content);"); - break; + writer.WriteBreak().WriteLine($"return JsonConvert.DeserializeObject<{this.GetTypeFullyResolvedName(routeResponse.ResponseType)}>(content);"); + } + else + { + switch (Type.GetTypeCode(routeResponse.ResponseType)) + { + case TypeCode.Boolean: + writer.WriteBreak().WriteLine("return bool.Parse(content);"); + break; - case TypeCode.Byte: - writer.WriteBreak().WriteLine("return byte.Parse(content);"); - break; + case TypeCode.Byte: + writer.WriteBreak().WriteLine("return byte.Parse(content);"); + break; - case TypeCode.Char: - writer.WriteBreak().WriteLine("return content[0];"); - break; + case TypeCode.Char: + writer.WriteBreak().WriteLine("return content[0];"); + break; - case TypeCode.DateTime: - writer.WriteBreak().WriteLine("return DateTime.Parse(content);"); - break; + case TypeCode.DateTime: + writer.WriteBreak().WriteLine("return DateTime.Parse(content);"); + break; - case TypeCode.Decimal: - writer.WriteBreak().WriteLine("return decimal.Parse(content);"); - break; + case TypeCode.Decimal: + writer.WriteBreak().WriteLine("return decimal.Parse(content);"); + break; - case TypeCode.Double: - writer.WriteBreak().WriteLine("return double.Parse(content);"); - break; + case TypeCode.Double: + writer.WriteBreak().WriteLine("return double.Parse(content);"); + break; - case TypeCode.Int16: - writer.WriteBreak().WriteLine("return short.Parse(content);"); - break; + case TypeCode.Int16: + writer.WriteBreak().WriteLine("return short.Parse(content);"); + break; - case TypeCode.Int32: - writer.WriteBreak().WriteLine("return int.Parse(content);"); - break; + case TypeCode.Int32: + writer.WriteBreak().WriteLine("return int.Parse(content);"); + break; - case TypeCode.Int64: - writer.WriteBreak().WriteLine("return long.Parse(content);"); - break; + case TypeCode.Int64: + writer.WriteBreak().WriteLine("return long.Parse(content);"); + break; - case TypeCode.SByte: - writer.WriteBreak().WriteLine("return sbyte.Parse(content);"); - break; + case TypeCode.SByte: + writer.WriteBreak().WriteLine("return sbyte.Parse(content);"); + break; - case TypeCode.Single: - writer.WriteBreak().WriteLine("return float.Parse(content);"); - break; + case TypeCode.Single: + writer.WriteBreak().WriteLine("return float.Parse(content);"); + break; - case TypeCode.String: - writer.WriteBreak().WriteLine("return content;"); - break; + case TypeCode.String: + writer.WriteBreak().WriteLine("return content;"); + break; - case TypeCode.UInt16: - writer.WriteBreak().WriteLine("return ushort.Parse(content);"); - break; + case TypeCode.UInt16: + writer.WriteBreak().WriteLine("return ushort.Parse(content);"); + break; - case TypeCode.UInt32: - writer.WriteBreak().WriteLine("return uint.Parse(content);"); - break; + case TypeCode.UInt32: + writer.WriteBreak().WriteLine("return uint.Parse(content);"); + break; - case TypeCode.UInt64: - writer.WriteBreak().WriteLine("return ulong.Parse(content);"); - break; + case TypeCode.UInt64: + writer.WriteBreak().WriteLine("return ulong.Parse(content);"); + break; - case TypeCode.Object: - throw new NotSupportedException("ResponseType isn't JSON but is an object."); + case TypeCode.Object: + throw new NotSupportedException("ResponseType isn't JSON but is an object."); + } } }