108 lines
5.1 KiB
C#
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;
|
|
}
|
|
}
|
|
} |