【问题标题】:How to make Swagger show examples of objects returned from the API?如何让 Swagger 显示从 API 返回的对象示例?
【发布时间】:2018-03-02 19:34:15
【问题描述】:

我是第一次创建一组 API。这是其中一种方法:

    // GET: api/Doors/0
    /// <summary>
    /// Get a list of all doors for a given organization.
    /// </summary>
    /// <param name="organizationSys">The Organization ID for which all doors should be retreived.</param>
    /// <returns></returns>
    [Route("{organizationSys:int}")]
    public IHttpActionResult Get(int organizationSys)
    {
        try
        {
            Dictionary<string, object> parameters = new Dictionary<string, object>();
            parameters.Add("@OrganizationSys", organizationSys);
            List<Door> doors = Repository<Doors>.GetList("WHERE OrganizationSys = @OrganizationSys", parameters).ToList();
            if (doors == null || doors.Count() == 0)
                return Content(HttpStatusCode.NotFound, RejectionMessage.NoItemsFound);

            return Ok(doors);
        }
        catch (Exception ex)
        {
            return Content(HttpStatusCode.BadRequest, ex.Message);
        }
    }

我已经为此端点设置了一个单元测试,它运行良好。不过,我确实有一个问题。

在 Swagger 中,我想展示一个将返回的数据对象的示例。该方法的唯一返回类型是IHttpActionResult,所以我并不惊讶它没有在 Swagger 中显示数据模型。那么,我需要对这个方法进行哪些更改,以使返回对象(在本例中为 List&lt;Door&gt;)更加可见?

Swashbuckle 支持这个吗?

谢谢!

【问题讨论】:

标签: c# .net api swagger swashbuckle


【解决方案1】:

这应该很简单:

[Route("{organizationSys:int}")]
[ProducesResponseType(typeof(List<Door>), 200)]
[ProducesResponseType(typeof(string), 400)]
public IHttpActionResult Get(int organizationSys)

请注意,由于您有 2 个退出点:一个是带数据的正常返回,一个是返回错误消息的 catch,我在上面的示例中定义了两种可能的结果类型:

  • http:200(OK) 与List&lt;Door&gt;
  • http:400(BadRequest) 与 string

Swashbuckle Swagger 基础设施将读取这些数据并提供非常粗略的这些案例的数据示例。

但是,如果您需要更详细的示例(即具有一些合理的字段值),那么您将不得不实现所谓的“示例提供者”。 See here for details and quick tutorial,简而言之:

[SwaggerRequestExample(typeof(DeliveryOptionsSearchModel), typeof(DeliveryOptionsSearchModelExample))]
public async Task<IHttpActionResult> DeliveryOptionsForAddress(DeliveryOptionsSearchModel search)

public class DeliveryOptionsSearchModelExample : IExamplesProvider
{
  public object GetExamples()
  {
    return new DeliveryOptionsSearchModel
    {
        Lang = "en-GB",
        Currency = "GBP",
        Address = new AddressModel
        {
            Address1 = "1 Gwalior Road",
            Locality = "London",
            Country = "GB",
            PostalCode = "SW15 1NP"
        },
        Items = new[]
        {
            new ItemModel
            {
                ItemId = "ABCD",
                ItemType = ItemType.Product,
                Price = 20,
                Quantity = 1,
                RestrictedCountries = new[] { "US" }
            }
        }
    };
}

示例提供程序的工作方式非常简单:无论提供程序返回什么,它都会被序列化为 JSON 并作为给定数据类型的示例返回。就这样。

现在,如果您的方法返回 DeliveryOptionsSearchModel,则提供者将直接使用上面的这些数据。

或者,如果您的方法返回了一个更大的对象,由 DeliveryOptionsSearchModel 和其他一些对象组成,那么 Swagger 会将此提供程序用于响应示例的一部分,并将其他提供程序(或默认粗略示例)用于所有响应示例大物体的其他部分。


以上所有内容均适用于 Net Core。

如果您使用“普通”Net 4.5/4.6/4.7,那么这种方式不可用,因为 Attribute 类不存在。在 Net 4.x 的 AspMvc 中,只有 [ResponseType(typeof(..))] 属性允许定义单个返回类型。大多数时候没关系。但是,如果您确实需要区分返回类型而不是响应代码,或者如果您需要提供好的示例,那就有问题了。

但是!一些好人已经解决了这个问题。见this article。它描述了 NuGet Swagger.Examples,我相信它是针对非核心的,它旨在提供更好的结果描述。

它定义了另一个属性 - [SwaggerResponse(HttpStatusCode.OK, Type=typeof(IEnumerable... 来定义可能的结果代码和结果类型,并为 Swagger 提供了使用该属性的插件。

它还提供了另一个属性[SwaggerResponseExample...,它允许您定义结果示例提供程序,它可以提供一个带有数据的自定义良好示例,就像上面为Core 描述的IExampleProvider。整洁!

【讨论】:

  • 太棒了!谢谢!看起来我需要为ProducesResponseType 使用命名空间,但我可以弄清楚。
  • 嗯。尽管已经有“使用 System.Web.Http.Description;”,但我得到“找不到类型或命名空间 ProducesResponseType”
  • @CaseyCrookston - 根据 ASP 和 Swagger NuGet 版本可能会有所不同。我目前使用的是 net core 2.0,而ProducesResponseType 位于 Assembly Microsoft.AspNetCore.Mvc.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60,所以不是真正来自 Swagger,而是来自 AspCore本身。
  • 4.6中是否存在?
  • @CaseyCrookston:见this article 它描述了NuGet Swagger.Examples,我相信它是针对非核心的,它旨在提供更好的示例。它定义并使用另一个属性 - [SwaggerResponse(HttpStatusCode.OK, Type=typeof(IEnumerable... 来定义可能的结果代码和结果类型,并使用 [SwaggerResponseExample... 来定义结果示例提供程序。整洁!
【解决方案2】:

对于 ASP.NET WebApi2,您可以使用属性 SwaggerResponse。这可以指定状态码和返回类型。

[SwaggerResponse(System.Net.HttpStatusCode.OK, Type = typeof(List<Door>))]
[SwaggerResponse(System.Net.HttpStatusCode.NotFound, Type = typeof(string))]

您可以在这里找到更多信息:https://mattfrear.com/2015/04/21/generating-swagger-example-responses-with-swashbuckle/

【讨论】:

    【解决方案3】:

    Core 的 IOperationFilter 没有架构注册表作为 Apply 方法实现中的参数

        public void Apply(Operation operation, OperationFilterContext context)
        {
            throw new NotImplementedException();
        }
    

    【讨论】:

    • @quetzalcoatl ,您能否更新示例和解决方法。
    猜你喜欢
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 2018-12-20
    • 1970-01-01
    • 2020-09-09
    • 2021-12-23
    • 2012-10-08
    • 2019-03-06
    相关资源
    最近更新 更多