要实现http接口,我正在使用RestEase插件。
在官方documentation之后,我实施了一个带有ApiException的try catch来管理http调用的400和500状态。
这是Try Catch:
try
{
var l = _provider.Api.GetHostListAsync();
response.HttpResponseData = l.Result.Data;
response.Status = "Success";
}
catch (ApiException ax)
{
response.Status = "Error";
_finalSuccess = false;
}
这是界面:
[Header("User-Agent", "ComunicationLayer")]
public interface ISapi
{
[Get("host")]
Task<SapiGeneralResponse<List<Host>>> GetHostListAsync();
}
...和初始化:
Api = RestClient.For<ISapi>(url);
答案200一切都成功,问题是当他们返回400和500没有从ApiException传递。
为了绕过这个问题,我试图在接口调用中实现属性[AllowAnyStatusCode],但在这种情况下我收到了一个错误:
Object reference not set to an instance of an object.
我正在使用.NetCore 2.1。 感谢
答案 0 :(得分:1)
您的异常未被捕获的原因是您在不等待任务的情况下使用l.Result.Data
(此外,它可以创建死锁,具体取决于您运行它的位置以及使用的同步上下文)。 / p>
try
{
var l = _provider.Api.GetHostListAsync();
response.HttpResponseData = l.Result.Data; // Don't do this
response.Status = "Success";
}
catch (ApiException ax)
{
response.Status = "Error";
_finalSuccess = false;
}
当您调用异步方法(返回任务时,除了在UI应用程序回调中应该避免async void
)时,您必须先等待它才能访问结果。
当您致电l.Result.Data
并且有异常时,它会抛出AggregateException
,其中可能包含您的ApiException
或其他一些异常类型。
当你await
方法时,将抛出实际的异常
编写该代码的正确方法是
try
{
var l = await _provider.Api.GetHostListAsync();
// l is now not a Task<T>, but T
response.HttpResponseData = l.Data;
response.Status = "Success";
}
catch (ApiException ax)
{
response.Status = "Error";
_finalSuccess = false;
}
现在当GetHostListAsync()
抛出ApiException
时,它会被捕获。
或者,当您被迫在同步上下文中运行此代码时,可以使用
task.GetAwaiter().GetResult();
这也会抛出ApiException
而不是AggregateException
。
答案 1 :(得分:-1)
可以尝试将界面更改为:
Task<Response<List<Host>>> GetHostListAsync();
并将try块中的代码更改为:
using (var response = await _provider.Api.GetHostListAsync())
{
if (response.ResponseMessage.StatusCode == HttpStatusCode.NotFound)
{
// User wasn't found
}
else
{
var user = response.GetContent();
// ...
}
}
这可以解决您的问题。