diff --git a/README.md b/README.md index 9ac783073..e1afd71a1 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,7 @@ There are four possibilities for supplying the body data, depending on the type of the parameter: * If the type is `Stream`, the content will be streamed via `StreamContent` -* If the type is `string`, the string will be used directly as the content +* If the type is `string`, the string will be used directly as the content unless `[Body(BodySerializationMethod.Json)]` is set which will send it as a `StringContent` * If the parameter has the attribute `[Body(BodySerializationMethod.UrlEncoded)]`, the content will be URL-encoded (see [form posts](#form-posts) below) * For all other types, the object will be serialized using the content serializer specified in diff --git a/samples/Meow.sln b/samples/Meow.sln new file mode 100644 index 000000000..053ba4e23 --- /dev/null +++ b/samples/Meow.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28711.60 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meow", "Meow\Meow.csproj", "{F89AADAA-1C9E-4125-B6CF-9AD1E6CD94F1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F89AADAA-1C9E-4125-B6CF-9AD1E6CD94F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F89AADAA-1C9E-4125-B6CF-9AD1E6CD94F1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F89AADAA-1C9E-4125-B6CF-9AD1E6CD94F1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F89AADAA-1C9E-4125-B6CF-9AD1E6CD94F1}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DCB37AC1-9A6D-4947-AA9D-61B0A757E0D6} + EndGlobalSection +EndGlobal diff --git a/samples/Meow/Meow.csproj b/samples/Meow/Meow.csproj new file mode 100644 index 000000000..f5a178d17 --- /dev/null +++ b/samples/Meow/Meow.csproj @@ -0,0 +1,14 @@ + + + + Exe + netcoreapp2.1 + + + + + + + + + diff --git a/samples/Meow/Middleware/HttpClientDiagnosticsHandler.cs b/samples/Meow/Middleware/HttpClientDiagnosticsHandler.cs new file mode 100644 index 000000000..178fc004f --- /dev/null +++ b/samples/Meow/Middleware/HttpClientDiagnosticsHandler.cs @@ -0,0 +1,50 @@ +using Serilog; +using System.Diagnostics; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace HttpClientDiagnostics +{ + [DebuggerStepThrough] + public class HttpClientDiagnosticsHandler : DelegatingHandler + { + public HttpClientDiagnosticsHandler(HttpMessageHandler innerHandler) : base(innerHandler) + { + } + + public HttpClientDiagnosticsHandler() + { + } + + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + var totalElapsedTime = Stopwatch.StartNew(); + + Log.Debug(string.Format("Request: {0}", request)); + if (request.Content != null) + { + var content = await request.Content.ReadAsStringAsync().ConfigureAwait(false); + Log.Debug(string.Format("Request Content: {0}", content)); + } + + var responseElapsedTime = Stopwatch.StartNew(); + var response = await base.SendAsync(request, cancellationToken); + + Log.Debug(string.Format("Response: {0}", response)); + if (response.Content != null) + { + var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + Log.Debug(string.Format("Response Content: {0}", content)); + } + + responseElapsedTime.Stop(); + Log.Debug(string.Format("Response elapsed time: {0} ms", responseElapsedTime.ElapsedMilliseconds)); + + totalElapsedTime.Stop(); + Log.Debug(string.Format("Total elapsed time: {0} ms", totalElapsedTime.ElapsedMilliseconds)); + + return response; + } + } +} \ No newline at end of file diff --git a/samples/Meow/Program.cs b/samples/Meow/Program.cs new file mode 100644 index 000000000..b5cf592f1 --- /dev/null +++ b/samples/Meow/Program.cs @@ -0,0 +1,28 @@ +using Serilog; +using System; +using System.Threading.Tasks; + +namespace Meow +{ + class Program + { + static void Main(string[] args) + { + Log.Logger = new LoggerConfiguration() + .WriteTo.Console() + .MinimumLevel.Verbose() + .CreateLogger(); + + Task.Run(() => AsyncMain()).Wait(); + } + + static async Task AsyncMain() + { + var service = new CatsService("https://api.thecatapi.com"); + var results = await service.Search("bengal"); + + Log.Debug("{results}", results); + + } + } +} diff --git a/samples/Meow/Responses/BreedsResponse.cs b/samples/Meow/Responses/BreedsResponse.cs new file mode 100644 index 000000000..18c2b57e9 --- /dev/null +++ b/samples/Meow/Responses/BreedsResponse.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Meow.Responses +{ + + public class BreedsResponse + { + public Class1[] Property1 { get; set; } + } + + public class Class1 + { + public Breed[] breeds { get; set; } + public string id { get; set; } + public string url { get; set; } + } + + public class Breed + { + public Weight weight { get; set; } + public string id { get; set; } + public string name { get; set; } + public string cfa_url { get; set; } + public string vetstreet_url { get; set; } + public string vcahospitals_url { get; set; } + public string temperament { get; set; } + public string origin { get; set; } + public string country_codes { get; set; } + public string country_code { get; set; } + public string description { get; set; } + public string life_span { get; set; } + public int indoor { get; set; } + public int lap { get; set; } + public int adaptability { get; set; } + public int affection_level { get; set; } + public int child_friendly { get; set; } + public int cat_friendly { get; set; } + public int dog_friendly { get; set; } + public int energy_level { get; set; } + public int grooming { get; set; } + public int health_issues { get; set; } + public int intelligence { get; set; } + public int shedding_level { get; set; } + public int social_needs { get; set; } + public int stranger_friendly { get; set; } + public int vocalisation { get; set; } + public int bidability { get; set; } + public int experimental { get; set; } + public int hairless { get; set; } + public int natural { get; set; } + public int rare { get; set; } + public int rex { get; set; } + public int suppressed_tail { get; set; } + public int short_legs { get; set; } + public string wikipedia_url { get; set; } + public int hypoallergenic { get; set; } + } + + public class Weight + { + public string imperial { get; set; } + public string metric { get; set; } + } + +} diff --git a/samples/Meow/Services/CatsService.cs b/samples/Meow/Services/CatsService.cs new file mode 100644 index 000000000..33db18da2 --- /dev/null +++ b/samples/Meow/Services/CatsService.cs @@ -0,0 +1,28 @@ +using HttpClientDiagnostics; +using Meow.Responses; +using Refit; +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; + +namespace Meow +{ + public class CatsService + { + private readonly HttpClient _httpClient; + private readonly ITheCatsAPI _theCatsApi; + + public CatsService(string baseUrl) + { + _httpClient = new HttpClient(new HttpClientDiagnosticsHandler()); + _theCatsApi = RestService.For(baseUrl); + } + + public async Task Search(string breed) + { + return await _theCatsApi.Search(breed).ConfigureAwait(false); + } + } +} diff --git a/samples/Meow/Services/ITheCatsAPI.cs b/samples/Meow/Services/ITheCatsAPI.cs new file mode 100644 index 000000000..3b2b7672a --- /dev/null +++ b/samples/Meow/Services/ITheCatsAPI.cs @@ -0,0 +1,17 @@ +using Meow.Responses; +using Refit; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace Meow +{ + [Headers("x-api-key: redacted")] + + public interface ITheCatsAPI + { + [Get("/v1/images/search")] + Task Search([AliasAs("breed_id")] string breedIdentifier); + } +}