我正在使用提供此操作的API:
[HttpGet]
[SwaggerOperation(OperationId = nameof(GetUsers))]
[SwaggerResponse(StatusCodes.Status200OK, "Result", typeof(List<UserModel>))]
[ProducesResponseType(typeof(List<UserModel>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ErrorModel), StatusCodes.Status400BadRequest)]
public async Task<IActionResult> GetUsers(string tenantId, int departmentId)
{
// Magically queries the users and returns OK or detect something is wrong and returns BadRequest
...
}
如果一切正常,此调用可以返回UserModel
的列表,如果请求错误,则可以返回ErrorModel
的列表。
使用swagger
和autorest
,我得到了一个自动生成的客户端,该客户端具有使用此方法返回对象的方法:
public async Task<HttpOperationResponse<object>> GetUsersWithHttpMessagesAsync(string tenantId, int departmentId, string commitReference = default(string), Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken))
{
...
}
在该方法中,算法检查状态码。如果状态码为200,则它将建立UserModel
的列表:
// Deserialize Response
if ((int)_statusCode == 200)
{
_responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
try
{
_result.Body = SafeJsonConvert.DeserializeObject<List<UserModel>>(_responseContent, DeserializationSettings);
}
catch (JsonException ex)
{
_httpRequest.Dispose();
if (_httpResponse != null)
{
_httpResponse.Dispose();
}
throw new SerializationException("Unable to deserialize the response.", _responseContent, ex);
}
}
但是,如果状态码为400,则将构建ErrorModel
的实例:
if ((int)_statusCode == 404)
{
_responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
try
{
_result.Body = SafeJsonConvert.DeserializeObject<ErrorModel>(_responseContent, DeserializationSettings);
}
catch (JsonException ex)
{
_httpRequest.Dispose();
if (_httpResponse != null)
{
_httpResponse.Dispose();
}
throw new SerializationException("Unable to deserialize the response.", _responseContent, ex);
}
}
因此,每当我使用此方法时,都必须检查返回的对象的类型,以了解我是否拥有UserModel
或ErrorModel
的列表。
当我调用自动生成的客户端时,我必须执行以下操作:
object result = await client.GetUserAsync(tenantId, departmentId);
switch (result)
{
case List<UserModel> userModels:
// Handle the users.
case ErrorModel errorModel:
// Handle the error.
}
这会在运行时(而不是编译时)推送任何类型的安全检查,从而可能导致错误。
问题
如何在C#中处理这种情况而不必依赖运行时类型检查?