Last active
October 22, 2023 16:33
-
-
Save cezarypiatek/d7cd41a0e7bf484e07a5ea9ea119c757 to your computer and use it in GitHub Desktop.
Example provider for Swashbuckle
This file contains 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
services.AddSwaggerGen(c => | |
{ | |
c.UseExampleFilter(e => | |
{ | |
e.DefineExample<AuthenticationController>(con => con.Login(new LoginCredentials | |
{ | |
Login = "cezarypiatek", | |
Password = "secret" | |
})); | |
e.DefineExamples<DiagnosticController>(ec => | |
{ | |
ec.DefineExample(con => con.StoreEventData(new EventStorageModel | |
{ | |
EventType = "GeneralEvent", | |
Details = new EventStorageDetails() | |
{ | |
Title = "Greeting", | |
Message = "Hello world" | |
} | |
})); | |
}); | |
}); | |
}); |
This file contains 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.Collections; | |
using System.Collections.Generic; | |
using System.Linq.Expressions; | |
using JetBrains.Annotations; | |
namespace SwaggerHelpers | |
{ | |
public class ExampleInvocationContainer<TController>:IEnumerable<Expression<Action<TController>>> | |
{ | |
private readonly IList<Expression<Action<TController>>> sampleInvocations = new List<Expression<Action<TController>>>(); | |
public void DefineExample([NotNull] Expression<Action<TController>> example) | |
{ | |
this.sampleInvocations.Add(example); | |
} | |
/// <inheritdoc /> | |
public IEnumerator<Expression<Action<TController>>> GetEnumerator() | |
{ | |
return this.sampleInvocations.GetEnumerator(); | |
} | |
/// <inheritdoc /> | |
IEnumerator IEnumerable.GetEnumerator() | |
{ | |
return this.GetEnumerator(); | |
} | |
} | |
} |
This file contains 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.Linq; | |
using JetBrains.Annotations; | |
using Microsoft.AspNetCore.Mvc.Controllers; | |
using Swashbuckle.AspNetCore.Swagger; | |
using Swashbuckle.AspNetCore.SwaggerGen; | |
namespace SwaggerHelpers | |
{ | |
[UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] | |
public class ExampleOperationFilter: IOperationFilter | |
{ | |
private readonly ExampleOperationFilterConfig config; | |
/// <inheritdoc /> | |
public ExampleOperationFilter(ExampleOperationFilterConfig config) | |
{ | |
this.config = config; | |
} | |
/// <inheritdoc /> | |
public void Apply([NotNull] Operation operation, [NotNull] OperationFilterContext context) | |
{ | |
if (context.ApiDescription.ActionDescriptor is ControllerActionDescriptor actionDescriptor && operation.Parameters != null) | |
{ | |
if (this.config.TryGetActionParametersExamples(actionDescriptor, out var parametersValues)) | |
{ | |
foreach (var parameter in operation.Parameters.OfType<BodyParameter>()) | |
{ | |
if (parametersValues.TryGetValue(parameter.Name, out var parameterValue)) | |
{ | |
parameter.Extensions.Add("default", parameterValue); | |
} | |
} | |
} | |
} | |
} | |
} | |
} |
This file contains 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.Collections.Generic; | |
using System.Linq; | |
using System.Linq.Expressions; | |
using JetBrains.Annotations; | |
using Microsoft.AspNetCore.Mvc.Controllers; | |
using Newtonsoft.Json; | |
namespace SwaggerHelpers | |
{ | |
public class ExampleOperationFilterConfig | |
{ | |
private readonly IDictionary<string, Dictionary<string,string>> invocationExamples = new Dictionary<string, Dictionary<string,string>>(); | |
[NotNull, Pure] | |
private static Dictionary<string, object> BuildParameterValuesFromExpression([NotNull] MethodCallExpression call) | |
{ | |
var parameterValues = new Dictionary<string, object>(); | |
var parameters = call.Method.GetParameters(); | |
if (parameters.Length > 0) | |
{ | |
for (int index = 0; index < parameters.Length; index++) | |
{ | |
var parameterExpression = call.Arguments[index]; | |
var value = Expression.Lambda(parameterExpression) | |
.Compile() | |
.DynamicInvoke(); | |
parameterValues.Add(parameters[index].Name, value); | |
} | |
} | |
return parameterValues; | |
} | |
public void DefineExample<TController>([NotNull] Expression<Action<TController>> sampleInvocation) | |
{ | |
var methodCall= (MethodCallExpression) sampleInvocation.Body; | |
var actionName = methodCall.Method.Name; | |
var controllerName = typeof(TController).Name.Replace("Controller", ""); | |
var key = GetActionKey(controllerName, actionName); | |
this.invocationExamples[key] = BuildParameterValuesFromExpression(methodCall) | |
.ToDictionary(x=>x.Key, x=> JsonConvert.SerializeObject(x.Value, Formatting.Indented)); | |
} | |
public void DefineExamples<TController>([NotNull] Action<ExampleInvocationContainer<TController>> configure) | |
{ | |
var exampleContainer = new ExampleInvocationContainer<TController>(); | |
configure(exampleContainer); | |
foreach (var example in exampleContainer) | |
{ | |
this.DefineExample(example); | |
} | |
} | |
[NotNull, Pure] | |
private static string GetActionKey(string controllerName, string actionName) | |
{ | |
return $"{controllerName}_{actionName}"; | |
} | |
[Pure] | |
public bool TryGetActionParametersExamples([NotNull] ControllerActionDescriptor c, out Dictionary<string, string> parametersValues) | |
{ | |
var actionKey = ExampleOperationFilterConfig.GetActionKey(c.ControllerName, c.ActionName); | |
return this.invocationExamples.TryGetValue(actionKey, out parametersValues); | |
} | |
} | |
} |
This file contains 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 JetBrains.Annotations; | |
using Swashbuckle.AspNetCore.SwaggerGen; | |
namespace SwaggerHelpers | |
{ | |
public static class ExmpleOperationFilterExtensions | |
{ | |
public static void UseExampleFilter([NotNull] this SwaggerGenOptions app, [NotNull] Action<ExampleOperationFilterConfig> configure) | |
{ | |
var configuration = new ExampleOperationFilterConfig(); | |
configure(configuration); | |
app.OperationFilter<ExampleOperationFilter>(configuration); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment