自动生成的c#客户端应该如何处理可以返回不同类型的API调用?

时间:2018-08-01 15:32:33

标签: c# asp.net-core swagger autorest

我正在使用具有以下定义的服务:

[HttpGet]
[SwaggerOperation(nameof(GetAnimal))]
[Route("{animalId:long}", Name = nameof(GetAnimal))]
[ProducesResponseType(typeof(AnimalModel), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ErrorModel), StatusCodes.Status500InternalServerError)]
public Task<IActionResult> GetAnimal(string tenantId, long animalId)
{
    try
    {
        // Find the actual animal.. somewhere.

        return Ok(new AnimalModel());      

    }
    catch (Exception exception)
    {
        return InternalServerError(new ErrorModel());
    }    
}

这似乎导致autorest生成一个以object作为返回类型的C#客户端(我猜是因为ProducesResponseType属性被指定了两次):

public async Task<HttpOperationResponse<object>> GetAnimalWithHttpMessagesAsync(string tenantId, long animalId, [..])

问题

处理返回不同对象的API的推荐方法是什么?

潜在的解决方案

  • 我可以修复客户端代码并强制转换结果以找到正确的类型(不好)。
  • 我可以修改API(如果可能的话),以便它仅返回一个由AnimalModelErrorModel组成的对象(可能更好)。

1 个答案:

答案 0 :(得分:0)

ActionResult<T>

  

ASP.NET Core 2.1为Web API控制器操作引入了ActionResult<T>返回类型。它使您可以返回源自ActionResult的类型或返回特定类型。与ActionResult<T>类型相比,IActionResult具有以下优点:

     
      
  • 可以排除[ProducesResponseType]属性的Type属性。例如,[ProducesResponseType(200, Type = typeof(Product))]简化为[ProducesResponseType(200)]。取而代之的是从T中的ActionResult<T>推断出操作的预期返回类型。
  •   
  • 隐式强制转换运算符支持将TActionResult都转换为ActionResult<T>T转换为ObjectResult,这意味着return new ObjectResult(T);简化为return T;
  •   

考虑使用新的ActionResult<T>并删除Produces响应属性  完全Type

[HttpGet]
[SwaggerOperation(nameof(GetAnimal))]
[Route("{animalId:long}", Name = nameof(GetAnimal))]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<AnimalModel>> GetAnimal(string tenantId, long animalId) {
    try {
        // Find the actual animal.. somewhere...using await.

        var model = new AnimalModel();

        //populate model    

        return model;
    } catch (Exception exception) {
        return InternalServerError(new ErrorModel());
    }
}