【问题标题】:How to generate JSON example values for class, just like Swagger does for example response?如何为类生成 JSON 示例值,就像 Swagger 对示例响应所做的那样?
【发布时间】:2020-11-21 07:05:18
【问题描述】:

我将 Swagger 与我的 ASP.NET Core 应用程序和返回 Blog 模型的 HTTP POST 端点一起使用:

[HttpPost]
[ProducesResponseType(typeof(Blog), StatusCodes.Status200OK)]
public IActionResult AddBlog([FromBody] string name)
{
    // Code removed for brevity...
    return Ok(newBlog);
}

博客:

public Blog
{
    public int Id { get; set; }

    public string Name { get; set; }
}

Swagger 在其 UI 中将显示该端点的示例响应:

{
  "Id": 0,
  "Name": "string"
}

我想做的是在 JSON 中为我提供的类的类型和我需要它的位置生成这样的示例值,这在我的应用程序的其他地方,例如:

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

这可能吗?

【问题讨论】:

  • 你想要一个字符串吗?
  • 不,我想要从 type 生成完整的 JSON。如果该类型具有嵌套属性,我希望 JSON 也能反映这一点。
  • 你的意思是something like this 但对于.NET?如果没有类似的.NET 库,您可以尝试通过IKVM 调用Java 库。或者您可以尝试使用mock server 来生成示例响应。
  • 或者,generate a JSON Schema 来自 C# 类,然后 use a JSON Schema "sampler" 从该架构生成示例 JSON。
  • @Helen 我想是的。谢谢你的链接和方向。肯定会试一试。终于有人明白我在这里问的是什么了:)

标签: c# asp.net-core swagger swagger-ui swagger-codegen


【解决方案1】:

您可以使用任何 JSON 库并序列化一个空对象。

使用 newtonsoft JSON

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

【讨论】:

  • 请删除这个答案,因为它不能解决我的问题。我在问题下的评论中解释了它。
  • 这没有回答问题。我建议删除。
【解决方案2】:

是的,可以为响应和 POST 请求生成此类示例值。对于获取请求,这很困难,请在此处查看我的问题:SwashBuckle Swagger-UI Example Request for HTTP GET Method with FromQuery Attribute

看看 NuGet 包Swashbuckle.AspNetCore.Filters

您可以定义如下示例响应:

public class BlogExample : IExamplesProvider<Blog>
{
    public Blog GetExamples()
    {
        return new Blog()
        {
            Id = 123,
            Name = "John Smith"
        };
    }
}

然后 SwaggerUI 将显示这些值而不是空的默认值。

【讨论】:

  • 我不需要返回具体的示例值,Swagger 生成的默认值就可以了。但我希望有一个通用生成器,它可以为我通过参数提供的任何类型返回示例值(正如有问题的示例用法中所示),而不仅仅是那些我将为其注册 IExamplesProvider 的类型。
【解决方案3】:

我最接近所需的生成器是使用库NJsonSchema。感谢@Helen 给了我关于 Json Schema 的宝贵指导。下面的用法示例:

public string Generate(Type type)
{
    return JsonSchema
        .FromType(type)
        .ToSampleJson()
        .ToString();
}

虽然它并不完美。例如,模型定义如下:

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; }
}

它会生成一个示例 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
  ]
}

可悲的是,NestedObject 属性不应该是 null,浮点类型应该具有示例值,表明它们确实是浮点类型,而不仅仅是 0 表明它们是整数类型。所以,是的,它可以改进。但总比没有好!

【讨论】:

  • 实际上这确实适用于更复杂的对象,但您需要在原始对象上使用RequiredDefaultValue 等属性来装饰属性。此外,Description 属性在生成 Json 模式时使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-06
  • 2018-08-22
  • 1970-01-01
  • 2015-12-02
  • 2017-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多