WebApiClientCore 异常处理

WebApiClientCore 集高性能高可扩展性于一体的声明式http客户端库,特别适用于微服务的restful资源请求,也适用于各种畸形http接口请求。

参考:https://github.com/dotnetcore/WebApiClient

记录笔记起因:

.net core mvc 项目使用 WebApiClientCore 调用 .net core api项目时,api做了授权管理。本想在mvc项目中通过过滤器拦截后的响应码做权限处理,发现过滤器始终没有执行。后来找到WebApiClientCore官网发现在接口请求异常中可以捕获到响应状态码异常,有了相应状态码就可以封装对象传给前端,前端通过判断状态码做相应的无权限处理。

WebApiClientCore 异常和异常处理官方原文:

请求一个接口,不管出现何种异常,最终都抛出HttpRequestException,HttpRequestException的内部异常为实际具体异常,之所以设计为内部异常,是为了完好的保存内部异常的堆栈信息。

WebApiClient内部的很多异常都基于ApiException这个抽象异常,也就是很多情况下,抛出的异常都是内为某个ApiException的HttpRequestException。

try
{
    var model = await api.GetAsync();
}
catch (HttpRequestException ex) when (ex.InnerException is ApiInvalidConfigException configException)
{
    // 请求配置异常
}
catch (HttpRequestException ex) when (ex.InnerException is ApiResponseStatusException statusException)
{
    // 响应状态码异常
}
catch (HttpRequestException ex) when (ex.InnerException is ApiException apiException)
{
    // 抽象的api异常
}
catch (HttpRequestException ex) when (ex.InnerException is SocketException socketException)
{
    // socket连接层异常
}
catch (HttpRequestException ex)
{
    // 请求异常
}
catch (Exception ex)
{
    // 异常
}

MVC 定义调用接口

[MiniShopApi]
[SetAccessToken]
[JsonReturn]
public interface IShopApi : IHttpApi
{
    [HttpGet("/api/Shop")]
    ITask<ResultModel<ShopDto>> GetByIdAsync(int id);

    [HttpGet("/api/Shop/GetByShopId")]
    ITask<ResultModel<ShopDto>> GetByShopIdAsync(Guid shopId);

    [HttpPost("/api/Shop")]
    ITask<ResultModel<ShopCreateDto>> AddAsync([JsonContent] ShopCreateDto model);

    [HttpPut("/api/Shop")]
    ITask<ResultModel<ShopUpdateDto>> PutUpdateAsync([JsonContent] ShopUpdateDto model);

    [HttpPatch("/api/Shop")]
    ITask<ResultModel<UserDto>> PatchUpdateByIdAsync(int id, [JsonContent] JsonPatchDocument<ShopUpdateDto> doc);
}

MVC调用接口封装

public async Task<IActionResult> ExecuteApiAsync<T>(Func<ITask<ResultModel<T>>> action)
{
    int statusCode;
    string msg;
    try
    {
        var result = await action();
        return Json(new Result() { Success = result.Success, Msg = result.Msg, Status = result.Status });
    }
    catch (HttpRequestException ex) when (ex.InnerException is ApiInvalidConfigException configException)
    {
        // 请求配置异常
        msg = configException.Message;
        statusCode = 500;
    }
    catch (HttpRequestException ex) when (ex.InnerException is ApiResponseStatusException statusException)
    {
        // 响应状态码异常
        msg = statusException.Message;
        statusCode = (int)statusException.StatusCode;
    }
    catch (HttpRequestException ex) when (ex.InnerException is ApiException apiException)
    {
        // 抽象的api异常
        msg = apiException.Message;
        statusCode = 500;
    }
    catch (HttpRequestException ex) when (ex.InnerException is SocketException socketException)
    {
        // socket连接层异常
        msg = socketException.Message;
        statusCode = 500;
    }
    catch (HttpRequestException ex)
    {
        // 请求异常
        msg = ex.Message;
        statusCode = 500;
    }
    catch (Exception ex)
    {
        msg = ex.Message;
        statusCode = 500;
    }
    return Json(new Result() { Success = false, Msg = msg, Status = statusCode });
}

MVC调用接口

[HttpPost]
public async Task<IActionResult> SaveAsync(ShopDto model)
{
    var dto = _mapper.Map<ShopUpdateDto>(model);
    var result = await ExecuteApiAsync(() => { return _shopApi.PutUpdateAsync(dto); });
    return result;
}

最后在mvc视图中对接口返回对象判断响应码403权限不足跳到指定试图即可。

发现数据验证异常也能捕获,属于HttpRequestException异常。

posted @ 2022-02-15 23:45  weichangk  阅读(466)  评论(0编辑  收藏  举报