自动生成的 c# 客户端应该如何处理可以 return 不同类型的 API 调用?
How is an auto-generated c# client supposed to handle an API call that can return different types?
我正在使用具有以下定义的服务:
[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
作为 return 类型的 C# 客户端(我猜是因为 ProducesResponseType
属性被指定了两次) :
public async Task<HttpOperationResponse<object>> GetAnimalWithHttpMessagesAsync(string tenantId, long animalId, [..])
问题
处理 return 个不同对象的 API 的推荐方法是什么?
可能的解决方案
- 我可以修复客户端代码并转换结果以找到正确的类型(不好)。
- 我可以修改 API(如果可能的话),使其 return 只有一个由
AnimalModel
和 ErrorModel
组成的对象(可能会更好) .
ASP.NET Core 2.1 introduces the ActionResult<T>
return type for Web API controller actions. It enables you to return a type deriving from ActionResult
or return a specific type. ActionResult<T>
offers the following benefits over the IActionResult
type:
- The
[ProducesResponseType]
attribute's Type
property can be excluded. For example, [ProducesResponseType(200, Type = typeof(Product))]
is simplified to [ProducesResponseType(200)]
. The action's expected return type is instead inferred from the T
in ActionResult<T>
.
- Implicit cast operators support the conversion of both
T
and ActionResult
to ActionResult<T>
. T
converts to ObjectResult
, which means return new ObjectResult(T);
is simplified to 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());
}
}
我正在使用具有以下定义的服务:
[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
作为 return 类型的 C# 客户端(我猜是因为 ProducesResponseType
属性被指定了两次) :
public async Task<HttpOperationResponse<object>> GetAnimalWithHttpMessagesAsync(string tenantId, long animalId, [..])
问题
处理 return 个不同对象的 API 的推荐方法是什么?
可能的解决方案
- 我可以修复客户端代码并转换结果以找到正确的类型(不好)。
- 我可以修改 API(如果可能的话),使其 return 只有一个由
AnimalModel
和ErrorModel
组成的对象(可能会更好) .
ASP.NET Core 2.1 introduces the
ActionResult<T>
return type for Web API controller actions. It enables you to return a type deriving fromActionResult
or return a specific type.ActionResult<T>
offers the following benefits over theIActionResult
type:
- The
[ProducesResponseType]
attribute'sType
property can be excluded. For example,[ProducesResponseType(200, Type = typeof(Product))]
is simplified to[ProducesResponseType(200)]
. The action's expected return type is instead inferred from theT
inActionResult<T>
.- Implicit cast operators support the conversion of both
T
andActionResult
toActionResult<T>
.T
converts toObjectResult
, which meansreturn new ObjectResult(T);
is simplified toreturn 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());
}
}