Skip to content

Commit

Permalink
Merge pull request #19 from itsharppro/dev
Browse files Browse the repository at this point in the history
(#18) update requests payloads serialization options
  • Loading branch information
SaintAngeLs authored Oct 5, 2024
2 parents 76499ce + b9b9231 commit 004e376
Show file tree
Hide file tree
Showing 13 changed files with 181 additions and 92 deletions.
97 changes: 43 additions & 54 deletions src/Nuar/src/Nuar/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,7 @@
using Nuar.Routing;
using Nuar.WebApi;
using Polly;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Mvc;
using System.Text;
using Microsoft.AspNetCore.Http;
using Nuar.Formatters;

[assembly: InternalsVisibleTo("Nuar.Tests.Unit")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
Expand Down Expand Up @@ -68,6 +64,7 @@ public static IServiceCollection AddNuar(this IServiceCollection services)
return services.AddCoreServices()
.ConfigureLogging(configuration)
.ConfigureHttpClient(configuration)
.ConfigurePayloads(configuration)
.AddNuarServices()
.AddExtensions(optionsProvider);
}
Expand All @@ -88,7 +85,6 @@ private static (NuarOptions, OptionsProvider) BuildConfiguration(IServiceCollect
return (options, optionsProvider);
}

// Step 2: Add custom JSON formatter using NetJSON
private static IServiceCollection AddCoreServices(this IServiceCollection services)
{
services.AddMvcCore(options =>
Expand Down Expand Up @@ -133,9 +129,24 @@ private static IServiceCollection ConfigureHttpClient(this IServiceCollection se
return services;
}

private static IServiceCollection ConfigurePayloads(this IServiceCollection services, NuarOptions options)
{
if (options.PayloadsFolder is null)
{
options.PayloadsFolder = "Payloads";
}

if (options.PayloadsFolder.EndsWith("/"))
{
options.PayloadsFolder = options.PayloadsFolder
.Substring(0, options.PayloadsFolder.Length - 1);
}

return services;
}

private static IServiceCollection AddNuarServices(this IServiceCollection services)
{
// Register core Nuar services
services.AddSingleton<IAuthenticationManager, AuthenticationManager>();
services.AddSingleton<IAuthorizationManager, AuthorizationManager>();
services.AddSingleton<IPolicyManager, PolicyManager>();
Expand Down Expand Up @@ -250,6 +261,31 @@ private class Nuar

private static void AddRoutes(this IApplicationBuilder app)
{

var options = app.ApplicationServices.GetRequiredService<NuarOptions>();
if (options.Modules is null)
{
return;
}

foreach (var route in options.Modules.SelectMany(m => m.Value.Routes))
{
if (route.Methods is {})
{
if (route.Methods.Any(m => m.Equals(route.Method, StringComparison.InvariantCultureIgnoreCase)))
{
throw new ArgumentException($"There's already a method {route.Method.ToUpperInvariant()} declared in route 'methods', as well as in 'method'.");
}

continue;
}

route.Method = (string.IsNullOrWhiteSpace(route.Method) ? "get" : route.Method).ToLowerInvariant();
route.DownstreamMethod =
(string.IsNullOrWhiteSpace(route.DownstreamMethod) ? route.Method : route.DownstreamMethod)
.ToLowerInvariant();
}

var routeProvider = app.ApplicationServices.GetRequiredService<IRouteProvider>();
app.UseRouting();
app.UseEndpoints(routeProvider.Build());
Expand Down Expand Up @@ -283,51 +319,4 @@ public static IApplicationBuilder UseRequestHandler<T>(this IApplicationBuilder
return app;
}
}

// Step 3: Define custom NetJSON input and output formatters
public class NetJsonInputFormatter : TextInputFormatter
{
public NetJsonInputFormatter()
{
SupportedMediaTypes.Add("application/json");
SupportedEncodings.Add(Encoding.UTF8);
}

protected override bool CanReadType(Type type)
{
return type != null;
}

public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
{
var request = context.HttpContext.Request;
using (var reader = new StreamReader(request.Body, encoding))
{
var body = await reader.ReadToEndAsync();
var result = NetJSON.NetJSON.Deserialize(context.ModelType, body);
return await InputFormatterResult.SuccessAsync(result);
}
}
}

public class NetJsonOutputFormatter : TextOutputFormatter
{
public NetJsonOutputFormatter()
{
SupportedMediaTypes.Add("application/json");
SupportedEncodings.Add(Encoding.UTF8);
}

protected override bool CanWriteType(Type type)
{
return type != null;
}

public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
{
var response = context.HttpContext.Response;
var json = NetJSON.NetJSON.Serialize(context.Object);
return response.WriteAsync(json);
}
}
}
30 changes: 30 additions & 0 deletions src/Nuar/src/Nuar/Formatters/NetJsonInputFormatter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Text;
using Microsoft.AspNetCore.Mvc.Formatters;

namespace Nuar.Formatters
{
public class NetJsonInputFormatter : TextInputFormatter
{
public NetJsonInputFormatter()
{
SupportedMediaTypes.Add("application/json");
SupportedEncodings.Add(Encoding.UTF8);
}

protected override bool CanReadType(Type type)
{
return type != null;
}

public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
{
var request = context.HttpContext.Request;
using (var reader = new StreamReader(request.Body, encoding))
{
var body = await reader.ReadToEndAsync();
var result = NetJSON.NetJSON.Deserialize(context.ModelType, body);
return await InputFormatterResult.SuccessAsync(result);
}
}
}
}
27 changes: 27 additions & 0 deletions src/Nuar/src/Nuar/Formatters/NetJsonOutputFormatter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Text;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Formatters;

namespace Nuar.Formatters
{
public class NetJsonOutputFormatter : TextOutputFormatter
{
public NetJsonOutputFormatter()
{
SupportedMediaTypes.Add("application/json");
SupportedEncodings.Add(Encoding.UTF8);
}

protected override bool CanWriteType(Type type)
{
return type != null;
}

public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
{
var response = context.HttpContext.Response;
var json = NetJSON.NetJSON.Serialize(context.Object);
return response.WriteAsync(json);
}
}
}
2 changes: 2 additions & 0 deletions src/Nuar/src/Nuar/Nuar.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
</None>

<FrameworkReference Include="Microsoft.AspNetCore.App" />

<PackageReference Include="MessagePack" Version="2.5.172" />
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.Routing" Version="2.2.2" />
Expand Down
26 changes: 22 additions & 4 deletions src/Nuar/src/Nuar/Requests/PayloadBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,33 +1,51 @@
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using NetJSON;

namespace Nuar.Requests
{
internal sealed class PayloadBuilder : IPayloadBuilder
{
public PayloadBuilder()
{
NetJSON.NetJSON.DateFormat = NetJSON.NetJSONDateFormat.ISO;
NetJSON.NetJSON.SkipDefaultValue = false;
NetJSON.NetJSON.TimeZoneFormat = NetJSON.NetJSONTimeZoneFormat.Utc;
}

public async Task<string> BuildRawAsync(HttpRequest request)
{
var content = string.Empty;
if (request.Body == null)
{
return content;
return string.Empty;
}

using (var reader = new StreamReader(request.Body))
{
content = await reader.ReadToEndAsync();
}

Console.WriteLine($"Incoming Payload: {content}");


}
return content;
}

public async Task<T> BuildJsonAsync<T>(HttpRequest request) where T : class, new()
{
var payload = await BuildRawAsync(request);

return string.IsNullOrWhiteSpace(payload) ? new T() : JsonConvert.DeserializeObject<T>(payload);
if (string.IsNullOrWhiteSpace(payload))
{
return new T();
}

var deserializedPayload = NetJSON.NetJSON.Deserialize<T>(payload);
Console.WriteLine($"Deserialized Payload: {NetJSON.NetJSON.Serialize(deserializedPayload)}");

return deserializedPayload;
}
}
}
13 changes: 7 additions & 6 deletions src/Nuar/src/Nuar/Requests/PayloadManager.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using Newtonsoft.Json;
using NetJSON;
using Nuar.Options;

namespace Nuar.Requests
Expand All @@ -19,17 +19,17 @@ public PayloadManager(NuarOptions options)

private IDictionary<string, PayloadSchema> LoadPayloads()
{
if (_options.Modules is null)
if (_options.Modules == null)
{
return new Dictionary<string, PayloadSchema>();
}

var payloads = new Dictionary<string, PayloadSchema>();
var modulesPath = _options.ModulesPath;
modulesPath = string.IsNullOrWhiteSpace(modulesPath)
? string.Empty
: (modulesPath.EndsWith("/") ? modulesPath : $"{modulesPath}/");

foreach (var module in _options.Modules)
{
foreach (var route in module.Value.Routes)
Expand All @@ -56,8 +56,9 @@ private IDictionary<string, PayloadSchema> LoadPayloads()
}

var json = File.ReadAllText(fullJsonPath);
dynamic expandoObject = new ExpandoObject();
JsonConvert.PopulateObject(json, expandoObject);

var expandoObject = NetJSON.NetJSON.Deserialize<ExpandoObject>(json);

var upstream = string.IsNullOrWhiteSpace(route.Upstream) ? string.Empty : route.Upstream;
if (!string.IsNullOrWhiteSpace(module.Value.Path))
{
Expand Down
Loading

0 comments on commit 004e376

Please sign in to comment.