-
-
Save benaadams/1b7b09aec462d5562d858ba163cf2cc0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Text.Json; | |
using System.Threading.Tasks; | |
using Microsoft.AspNetCore.Http; | |
using Microsoft.Extensions.DependencyInjection; | |
using static Microsoft.AspNetCore.Builder.ArgumentType; | |
namespace Microsoft.AspNetCore.Builder | |
{ | |
public static class RequestDelegateExtensions | |
{ | |
public static RequestDelegate Bind<TArg, TResult>(this Func<TArg, Task<TResult>> handler, From arg = default, JsonSerializerOptions options = null) | |
{ | |
return async context => | |
{ | |
var result = await handler(await Bind<TArg>(context, arg)); | |
context.Response.ContentType = "application/json"; | |
await JsonSerializer.SerializeAsync(context.Response.Body, result, options); | |
}; | |
} | |
public static RequestDelegate Bind<T>(this Func<Task<T>> handler, JsonSerializerOptions options = null) | |
{ | |
return async context => | |
{ | |
var result = await handler(); | |
context.Response.ContentType = "application/json"; | |
await JsonSerializer.SerializeAsync(context.Response.Body, result, options); | |
}; | |
} | |
public static RequestDelegate Bind<T>(this Func<T, HttpContext, Task> handler, From arg = null) | |
{ | |
return async context => await handler(await Bind<T>(context, arg), context); | |
} | |
public static RequestDelegate Bind<T1, T2>(this Func<T1, T2, HttpContext, Task> handler, From arg1 = null, From arg2 = null) | |
{ | |
return async context => await handler(await Bind<T1>(context, arg1), await Bind<T2>(context, arg2), context); | |
} | |
public static RequestDelegate Bind<T1, T2, T3>(this Func<T1, T2, T3, HttpContext, Task> handler, From arg1 = null, From arg2 = null, From arg3 = null) | |
{ | |
return async context => await handler(await Bind<T1>(context, arg1), await Bind<T2>(context, arg2), await Bind<T3>(context, arg3), context); | |
} | |
public static RequestDelegate Bind<T1, T2, T3, T4>(this Func<T1, T2, T3, T4, HttpContext, Task> handler, From arg1 = null, From arg2 = null, From arg3 = null, From arg4 = null) | |
{ | |
return async context => await handler( | |
await Bind<T1>(context, arg1), | |
await Bind<T2>(context, arg2), | |
await Bind<T3>(context, arg3), | |
await Bind<T4>(context, arg4), context); | |
} | |
private static async ValueTask<T> Bind<T>(HttpContext context, From a) | |
{ | |
var request = context.Request; | |
return a.Type switch | |
{ | |
Query => ChangeType<T>(request.Query[a.Name]), | |
Route => ChangeType<T>(request.RouteValues[a.Name]), | |
Form => ChangeType<T>((await request.ReadFormAsync())[a.Name]), | |
Body => await JsonSerializer.DeserializeAsync<T>(request.Body, a.Options), | |
_ => context.RequestServices.GetRequiredService<T>() | |
}; | |
} | |
private static T ChangeType<T>(object value) => (T)Convert.ChangeType(value, typeof(T)); | |
} | |
public class From | |
{ | |
internal string Name { get; set; } | |
internal ArgumentType Type { get; set; } | |
internal JsonSerializerOptions Options { get; set; } | |
public static From Query(string name) => new From { Name = name, Type = ArgumentType.Query }; | |
public static From Route(string name) => new From { Name = name, Type = ArgumentType.Route }; | |
public static From Form(string name) => new From { Name = name, Type = ArgumentType.Form }; | |
public static From Body(JsonSerializerOptions options = null) => new From { Type = ArgumentType.Body, Options = options }; | |
} | |
public enum ArgumentType | |
{ | |
Service, | |
Query, | |
Route, | |
Form, | |
Body | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment