Is there a way to exclude/remove properties from your example value?
I'm using XML comments on my models to provide information on the swagger page with c.IncludeXmlComments
I use the ///<example>Example Value</example>
XML tag to set the example values. My request model does not require all the fields to be set by default, but if I don't set an example XML tag the example value is translated to it's type. Looking like this
{
"ID": "string",
"ExampleSetValue": "Example Value"
}
And I want my example value to only contain the ExampleSetValue property so my example value looks like this
{
"ExampleSetValue": "Example Value"
}
This is the swagger setup in my startup
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", openApiInfo);
c.AddSecurityDefinition("Bearer", openApiSecurityScheme);
c.AddSecurityRequirement(openApiSecurityRequirement);
// Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
My Request Model
public class CreateRequest
{
/// <summary>
/// ID of the user if available
/// </summary>
public string ID { get; set; }
/// <summary>
/// ExampleSetValue
/// </summary>
/// <example>Example Value</example>
public string ExampleSetValue { get; set; }
}
CodePudding user response:
Xml comment seems cannot be used to exclude the property.
If you want to ignore the property, I suggest you use the [System.Text.Json.Serialization.JsonIgnore]
attribute. But in this way it will also make your property hidden when you serialize or deserialize the data.
public class CreateRequest
{
/// <summary>
/// ID of the user if available
/// </summary>
[JsonIgnore] //add this..........
public string ID { get; set; }
/// <summary>
/// ExampleSetValue
/// </summary>
/// <example>Example Value</example>
public string ExampleSetValue { get; set; }
}
If you only want to exclude the property from example value, you need custom ISchemaFilter:
Model:
public class CreateRequest
{
/// <summary>
/// ID of the user if available
/// </summary>
[IgnoreDataMember] //add this..........
public string ID { get; set; }
/// <summary>
/// ExampleSetValue
/// </summary>
/// <example>Example Value</example>
public string ExampleSetValue { get; set; }
}
Custom ISchemaFilter:
public class MySwaggerSchemaFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
if (schema?.Properties == null)
{
return;
}
var ignoreDataMemberProperties = context.Type.GetProperties()
.Where(t => t.GetCustomAttribute<IgnoreDataMemberAttribute>() != null);
foreach (var ignoreDataMemberProperty in ignoreDataMemberProperties)
{
var propertyToHide = schema.Properties.Keys
.SingleOrDefault(x => x.ToLower() == ignoreDataMemberProperty.Name.ToLower());
if (propertyToHide != null)
{
schema.Properties.Remove(propertyToHide);
}
}
}
}
Register the filter:
services.AddSwaggerGen(c =>
{
//......
c.SchemaFilter<MySwaggerSchemaFilter>();
});
CodePudding user response:
I found a different approach which suited my case exactly how I wanted. You can set an example object on your schema which is of type OpenApiObject.
I Created a Document filter to which loops over the schemas in my swagger.
public class AddExamplesFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
foreach (var schema in context.SchemaRepository.Schemas)
{
schema.Value.Example = ExampleManager.GetExample(schema.Key);
}
}
}
Created the ExampleManager class which returns the example object I want according to the schema name.
public static OpenApiObject GetExample(string requestModelName)
{
return requestModelName switch
{
"ObjectExample" => ObjectExample.GetExample(),
_ => null
};
}
And as the final step created an example class which corresponds exactly on how I want my example to look like. Where I used the OpenApiObject class
public static class ObjectExample
{
public static OpenApiObject GetExample()
{
return new OpenApiObject
{
["ObjectInsideObject"] = new OpenApiObject
{
["Name"] = new OpenApiString("name"),
},
["ArrayWithObjects"] = new OpenApiArray
{
new OpenApiObject
{
["Object"] = new OpenApiObject
{
["integer"] = new OpenApiInteger(15),
},
["Description"] = new OpenApiString("description")
}
},
["date"] = new OpenApiDate(new DateTime().AddMonths(1)),
["Description"] = new OpenApiString("description"),
};
}
}