简体   繁体   English

如何为 class 生成 JSON 示例值,就像 Swagger 的示例响应一样?

[英]How to generate JSON example values for class, just like Swagger does for example response?

I'm using Swagger with my ASP.NET Core application and for a HTTP POST endpoint returning Blog model:我将 Swagger 与我的 ASP.NET Core 应用程序一起使用,并用于 HTTP POST 端点返回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:其 UI 中的 Swagger 将显示该端点的示例响应:

{
  "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:我想做的是在 JSON 中为我提供的 class 类型以及我需要它的地方生成这样的示例值,这是我应用程序中的其他地方,例如:

var json = exampleValuesGenerator.Generate(typeof(Blog));

Is this possible?这可能吗?

Yes, it's possible to generate such example values for responses and for POST request.是的,可以为响应和 POST 请求生成此类示例值。 For Get requests, it's difficult, see my question here: SwashBuckle Swagger-UI Example Request for HTTP GET Method with FromQuery Attribute对于获取请求,这很困难,请在此处查看我的问题: SwashBuckle Swagger-UI Example Request for HTTP GET Method with FromQuery Attribute

Have a look at the NuGet package Swashbuckle.AspNetCore.Filters :看看 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.然后 SwaggerUI 将显示这些值而不是空的默认值。

Closest I've come to the desired generator is by using a library NJsonSchema .最接近我想要的生成器是使用库NJsonSchema Thanks to @Helen for giving me valuable directions to Json Schema.感谢@Helen 给了我关于 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:例如,对于 model 定义如下:

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:它生成一个样本 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.可悲的是, NestedObject属性是null ,而浮点类型应该具有示例值,表明它们确实是浮点类型,而不仅仅是0 ,表明它们是 integer 类型。 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: NJsonSchema可以很好地为CLR类型生成示例 json:

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.悬停,如果Foo具有嵌套的复杂类型作为属性,则必须添加其他属性,例如[Required]才能使事情正常进行。

As a result,i prefer to combine AutoFixture with NJsonSchema to generate the sample json,here is the example:因此,我更喜欢将AutoFixtureNJsonSchema结合起来生成示例 json,示例如下:

[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.您可以使用任何 JSON 库并序列化一个空的 object。

Using newtonsoft JSON使用newtonsoft JSON

var json = JsonConvert.SerializeObject(new Blog());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM