在ASP.NET Core中,是否存在一种将成功的对象或状态代码和响应主体传播给typed HTTP client的使用者的好方法?
提供以下API服务:
public class TestApiService
{
private readonly HttpClient _httpClient;
public TestApiService(HttpClient httpClient)
{
httpClient.BaseAddress = new Uri("https://localhost:5000");
_httpClient = httpClient;
}
public async Task<string> GetVersion()
{
var response = await _httpClient.GetAsync("/api/v1/version");
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync();
}
return null;
}
}
通过以下方式在DI容器中注册:
services.AddHttpClient<TestApiService>();
如果响应成功或响应失败,我想从string
方法返回TestApiService.GetVersion()
值。返回状态代码和响应正文。
似乎无法执行以下操作:
public async Task<string> GetVersion()
{
var response = await _httpClient.GetAsync("/api/v1/version");
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
并获得理想的结果,因为从HttpRequestException抛出的HttpResponseMessage.EnsureSuccessStatusCode()不包括状态码或响应正文。
在GitHub上有一个open issue,但我不确定它是否会很快实现。
虽然ActionResult确实存在,但实际上似乎是用于控制器层的,所以我不确定在这里使用它是否适合该类的使用,或者是否有更好的方法来获取所需的类结果吗?
应该可以创建自己的异常类,然后将其从服务中抛出,但是如果要使用某种内置机制,我真的想避免这种情况。
答案 0 :(得分:1)
删除response.EnsureSuccessStatusCode(),这基本上是在检查状态,如果不是200,则抛出异常。考虑使用response.IsSuccessStatusCode或手动检查响应状态代码。两种方法都可以防止引发您不想要的异常。
if (HttpStatusCode.Ok == response.StatusCode)
{
// Read your result
}
else if ( // handle the specific failure case was it a 404 or a 401)
{
string value = await response.Content?.ReadAsStringAsync();
// Read your failed result
return $"{response.StatusCode} {value}".Trim()";
}
下一个问题是如何处理服务的失败者并将其传达给服务的被呼叫者?您是否希望服务对客户端应用程序不透明?
由于您的代码仅返回字符串,因此您是否考虑过返回其他内容,例如包含对象{Success = true | false,Error =“”,ErrorCode = 1234,Data =“ value”},或者只是抛出一个适当的异常来传达故障的性质。例如。您可能要抛出适当的异常,例如TestApiException,其中TestApiException可能带有ErrorCode或您需要的任何内容。