Created
February 9, 2020 02:11
-
-
Save davidfowl/7c972ec7b16f5c03d3d2cac2c1bab30b 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; | |
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) | |
{ | |
if (a.Type == ArgumentType.Query) | |
{ | |
return (T)Convert.ChangeType(context.Request.Query[a.Name], typeof(T)); | |
} | |
else if (a.Type == ArgumentType.Route) | |
{ | |
return (T)Convert.ChangeType((string)context.Request.RouteValues[a.Name], typeof(T)); | |
} | |
else if (a.Type == ArgumentType.Form) | |
{ | |
var form = await context.Request.ReadFormAsync(); | |
return (T)Convert.ChangeType(form[a.Name], typeof(T)); | |
} | |
else if (a.Type == ArgumentType.Body) | |
{ | |
return await JsonSerializer.DeserializeAsync<T>(context.Request.Body, a.Options); | |
} | |
return context.RequestServices.GetRequiredService<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