I'm using Swagger with my ASP.NET Core application and for a HTTP POST endpoint returning Blog
model:
[HttpPost]
[ProducesResponseType(typeof(Blog), StatusCodes.Status200OK)]
public IActionResult AddBlog([FromBody] string name)
{
// Code removed for brevity...
return Ok(newBlog);
}
Blog:
public Blog
{
public int Id { get; set; }
public string Name { get; set; }
}
Swagger in its UI will show example response for that endpoint:
{
"Id": 0,
"Name": "string"
}
What I'd like to do is to generate such example values in JSON for type of class I provide and where I need it, which is somewhere else in my application like:
var json = exampleValuesGenerator.Generate(typeof(Blog));
Is this possible?
Yes, it's possible to generate such example values for responses and for POST request. For Get requests, it's difficult, see my question here: SwashBuckle Swagger-UI Example Request for HTTP GET Method with FromQuery Attribute
Have a look at the NuGet package Swashbuckle.AspNetCore.Filters :
You can define an example response such as this:
public class BlogExample : IExamplesProvider<Blog>
{
public Blog GetExamples()
{
return new Blog()
{
Id = 123,
Name = "John Smith"
};
}
}
SwaggerUI will then show these values instead of the empty default values.
Closest I've come to the desired generator is by using a library NJsonSchema . Thanks to @Helen for giving me valuable directions to Json Schema. Usage example below:
public string Generate(Type type)
{
return JsonSchema
.FromType(type)
.ToSampleJson()
.ToString();
}
It isn't perfect though. For example, for model defined as follows:
public class User
{
public string String { get; set; }
public int Int { get; set; }
public double Double { get; set; }
public float Float { get; set; }
public short Short { get; set; }
public byte Byte { get; set; }
public long Long { get; set; }
public decimal Decimal { get; set; }
public DateTime DateTime { get; set; }
public TimeSpan TimeSpan { get; set; }
public bool Bool { get; set; }
public BindingFlags Enum2 { get; set; }
public Blog NestedObject { get; set; }
public Blog[] ArrayOfObjects { get; set; }
public int[] ArrayOfValues { get; set; }
}
public class Blog
{
public int Id { get; set; }
public string Name { get; set; }
}
it generates a sample JSON:
{
"String": "String",
"Int": 0,
"Double": 0,
"Float": 0,
"Short": 0,
"Byte": 0,
"Long": 0,
"Decimal": 0,
"DateTime": "2020-08-02T19:43:59.8759099+00:00",
"TimeSpan": "TimeSpan",
"Bool": false,
"Enum2": 0,
"NestedObject": null,
"ArrayOfObjects": [
{
"Id": 0,
"Name": "Name"
}
],
"ArrayOfValues": [
0
]
}
Sadly NestedObject
property is null
when it shouldn't be and floating point types should have example value suggesting they are indeed floating type, not just 0
suggesting that they are of integer type. So yeah, it could be improved. But it's definitely better than nothing!
NJsonSchema
is fine to generate the sample json for a CLR
type:
var sampleJson = JsonSchema.FromType(typeof(Foo)).ToSampleJson().ToString();
Hoverer,if Foo
has nested complex type as properties,you have to add additional attribute such as [Required]
to make things work.
As a result,i prefer to combine AutoFixture
with NJsonSchema
to generate the sample json,here is the example:
[Fact]
public void Test1()
{
var sampleJson = JsonConvert.SerializeObject(new Fixture().Create<Foo>());
var str = JsonSchema.FromSampleJson(sampleJson).ToSampleJson();
File.WriteAllText(Path.Combine(Path.GetTempPath(),Path.GetTempFileName()),str.ToString());
}
You can use any JSON library and serialise an empty object.
Using newtonsoft JSON
var json = JsonConvert.SerializeObject(new Blog());
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.