NejCommon.NET/Controllers/TypedResultsPolyfill.cs
2024-12-03 01:02:02 +01:00

108 lines
5.1 KiB
C#

using System.Diagnostics.Eventing.Reader;
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace NejCommon.Controllers
{
public class TypedResultsMetadataProvider : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var responseType = context.MethodInfo.ReturnType;
//Console.WriteLine(context.MethodInfo.DeclaringType.Name);
//Console.WriteLine(context.MethodInfo.Name);
//Console.WriteLine(responseType);
var t = IsSubclassOfRawGeneric(typeof(Microsoft.AspNetCore.Http.HttpResults.Results<,>), responseType);
if (t == null)
{
return;
}
var parArg = t.GetGenericArguments();
if (operation.Responses.ContainsKey("200"))
operation.Responses.Remove("200");
foreach (var arg in parArg)
{
if (arg == typeof(NotFound))
{
operation.Responses.Add("404", new OpenApiResponse { Description = "Not found" });
}
else if (arg == typeof(Ok))
{
operation.Responses.Add("200", new OpenApiResponse { Description = "Success" });
}
else if (IsSubclassOfRawGeneric(typeof(Ok<>), arg) != null)
{
var okArg = IsSubclassOfRawGeneric(typeof(Ok<>), arg).GetGenericArguments()[0];
// Console.WriteLine("Adding: " + okArg);
//get or generate the schema
var schema = context.SchemaGenerator.GenerateSchema(okArg, context.SchemaRepository);
operation.Responses.Add("200", new OpenApiResponse { Description = "Success", Content = { { "application/json", new OpenApiMediaType { Schema = schema } } } });
}
else if (arg == typeof(CreatedAtRoute))
{
operation.Responses.Add("201", new OpenApiResponse { Description = "Success" });
}
else if (IsSubclassOfRawGeneric(typeof(CreatedAtRoute<>), arg) != null)
{
if (operation.Responses.ContainsKey("201"))
operation.Responses.Remove("201");
var okArg = IsSubclassOfRawGeneric(typeof(CreatedAtRoute<>), arg).GetGenericArguments()[0];
// Console.WriteLine("Adding: " + okArg);
//get or generate the schema
var schema = context.SchemaGenerator.GenerateSchema(okArg, context.SchemaRepository);
operation.Responses.Add("201", new OpenApiResponse { Description = "Success", Content = { { "application/json", new OpenApiMediaType { Schema = schema } } } });
}
else if (arg == typeof(BadRequest))
{
operation.Responses.Add("400", new OpenApiResponse { Description = "There was an error" });
}
else if (IsSubclassOfRawGeneric(typeof(BadRequest<>), arg) != null)
{
if (operation.Responses.ContainsKey("400"))
operation.Responses.Remove("400");
var okArg = IsSubclassOfRawGeneric(typeof(BadRequest<>), arg).GetGenericArguments()[0];
// Console.WriteLine("Adding: " + okArg);
//get or generate the schema
var schema = context.SchemaGenerator.GenerateSchema(okArg, context.SchemaRepository);
operation.Responses.Add("400", new OpenApiResponse { Description = "There was an error", Content = { { "application/json", new OpenApiMediaType { Schema = schema } } } });
}
else if (arg == typeof(FileStreamHttpResult)){
operation.Responses.Add("200", new OpenApiResponse { Description = "Success", Content = { { "application/octet-stream", new OpenApiMediaType { Schema = new OpenApiSchema { Type = "string", Format = "binary" } } } } });
}
else
{
Console.WriteLine("Unknown type: " + arg);
}
}
}
static Type? IsSubclassOfRawGeneric(Type generic, Type toCheck)
{
while (toCheck != null && toCheck != typeof(object))
{
//if Task is used, we need to check the underlying type
var realTypeNoTask = toCheck.IsGenericType && toCheck.GetGenericTypeDefinition() == typeof(Task<>) ? toCheck.GetGenericArguments()[0] : toCheck;
var cur = realTypeNoTask.IsGenericType ? realTypeNoTask.GetGenericTypeDefinition() : realTypeNoTask;
//Console.WriteLine(cur);
if (generic == cur)
{
return realTypeNoTask;
}
toCheck = toCheck.BaseType;
}
return null;
}
}
}