U rao U rao - 2 months ago 25
C# Question

Assign Default Request Data in Model Schema on Swagger UI using Swagger 6.0.0-rc1-final

Please help me out in implementing default request data to the model schema on the Swagger UI with Swagger 6.0.0-rc1-final with C#.

i found relevant answer for this but not the exact answer at https://mattfrear.com/2016/01/25/generating-swagger-example-requests-with-swashbuckle.

Above link works for Swagger 5.0, As i'm using Swagger 6.0.0-rc1-final, the functions(GetControllerAndActionAttributes and many more) which are used at above link are not found in this swagger which i’m using.

Anyone worked with Swagger 6.0.0-rc1-final, Please post your answer?

Operation Filter Class:

public class SwaggerFilter : IOperationFilter
{
public void Apply(Operation operation, OperationFilterContext context)
{
ReqModelExamples(operation, context);
}

private static void ReqModelExamples(Operation operation, OperationFilterContext context)
{
ReqExamplesAttribute exampleAttr = context.ApiDescription.GetActionAttributes().Where(x => x is ReqExamplesAttribute ).Cast<ReqExamplesAttribute >().FirstOrDefault();

if (exampleAttr != null)
{
var oExample =(IProvideExamples)Activator.CreateInstance(exampleAttr.SamplesProviderType);

oExample = context.SchemaRegistry.Definitions.First();
}
}


Controller Class :
[HttpGet("{id}")]
[ReqExamples(typeof(SampleReqModel))]
public string Get(SampleBO id)
{
....
}

SampleReqModel Class:
public class SampleReqModel : IProvideExamples
{
public object GetExamples()
{
return new SampleBO
{
str1 = "test",
};
}
}

ReqModelExamples :

[AttributeUsage(AttributeTargets.Method)]
public class ReqModelExamplesAttribute : Attribute
{
public ReqModelExamplesAttribute(Type responseType, Type samplesProviderType)
{
ResponseType = responseType;
SamplesProviderType = samplesProviderType;
}

public Type SamplesProviderType { get; private set; }

public Type ResponseType { get; private set; }
}


Startup.Swagger:
Config.OperationFilter();

Answer

Redoing the answer to this to make it more clear.

1) you'll need to create a RequestExampleAttribute class that just keeps the example class type similar to the link you sent.

2) decorate the action method with the RequestExampleAttribute:

[RequestExample(typeof(MyRequestExample))]

3) MyRequestExample is a simple class derived from your model, except it has all the properties populated with example values in the constructor

4) Create the operation filter as in your link

5) In the operation filter, find the attribute (should only be one or none):

RequestExampleAttribute exampleAttr = context.ApiDescription.GetActionAttributes().Where(x => x is RequestExampleAttribute).Cast<RequestExampleAttribute>().FirstOrDefault();

6) if exampleAttr is null, return, otherwise, new up an instance of the type with Activator.CreateInstance()

7) set context.SchemaRegistry.Definitions[0].Example to instance created.

object oExample = Activator.CreateInstance(exampleAttr.ExampleType);

context.SchemaRegistry.Definitions[0].Example = oExample;

8) check if it works... if not, continue to step 9

9) if its not reading from ...[0].Example, it is reading from the property schema, so you'll need to modify all the properties:

context.SchemaRegistry.Definitions[0].Properties[x].Value.Example

This is just a dictionary key/value pair with the property name in the key. What I did in my code was I loop through the dictionary keys and then use regex to pull the value from the serialized instance created in step #6. I.e.

{
  "prop1" : "value1"
}

so when you loop through the dictionary, the first key will be "prop1" for example, so you can use regex to pull "prop1": [string] and then copy that string to the Value.Example for the prop.

Hopefully you won't need to do that since the successful return model reads from the "easy" place to modify, so hopefully the request will also pull from the "easy" place.

Make sense now?

Comments