【问题标题】:Client-side multiple api responses handling客户端多个 api 响应处理
【发布时间】:2020-12-16 17:10:02
【问题描述】:

我的 api 有一个返回多种响应类型的方法:GetTokenResponseErrorsResponseErrorResponse

[HttpPost("token")]
[ProducesResponseType(typeof(GetTokenResponse), (int)HttpStatusCode.OK)]
[ProducesResponseType(typeof(ErrorsResponse), (int)HttpStatusCode.BadRequest)]
[ProducesResponseType(typeof(ErrorResponse), (int)HttpStatusCode.Forbidden)]
public async Task<IActionResult> GetToken([FromBody] GetTokenRequest request)
{
    try
    {
        var token = await _authService.LoginAsync(request.Email, request.Password);
        return Ok(new GetTokenResponse { Token = token });
    }
    catch (Exception ex) when (ex is UserNotFoundException || ex is InvalidPasswordException)
    {
        return BadRequest(new ErrorsResponse("Invalid username or password."));
    }
    catch (EmailNotConfirmedException ex)
    {
        return StatusCode((int)HttpStatusCode.Forbidden, new ErrorResponse(ex.Message));
    }
}

并且客户端服务有一个方法来发出请求

public async Task<bool> LoginAsync(GetTokenRequest request)
{
    var response = await _client.PostAsJsonAsync($"{_apiUrl}{Requests.Token}", request);

    if (response.StatusCode != HttpStatusCode.OK)
    {
        return false;
    }

    var responseString = await response.Content.ReadAsStringAsync();
    var result = JsonConvert.DeserializeObject<GetTokenResponse>(responseString);
    await Authenticate(result.Token, request.Email);

    return true;
}

在当前的实现方法中可以返回true或false,只处理GetTokenResponse但我想处理所有响应类型。其实这是个问题。最好的方法是什么? 我考虑过从服务返回响应内容并在调用方解析响应类型,为响应创建一个基本响应类型\包装器,但最佳实践怎么说?

【问题讨论】:

  • 看看这个包装器。 github.com/hassanhabib/RESTFulSense 我在 youtube 上的作者视频中看到了它。 BLZ001:Blazor 简介
  • 如何制作ErrorResponse和抽象类并在GetTokenResponse中实现,这样就可以返回单一类型?然后客户端应用程序可以检查是否存在来自 ErrorResponse 的属性,例如 IsError bool 或类似的?

标签: c# asp.net-web-api asp.net-core-webapi blazor blazor-client-side


【解决方案1】:

我添加了引发异常的扩展方法 EnsureSuccess()

public async Task LoginAsync(GetTokenRequest request)
{
    var response = await _client.PostAsJsonAsync($"{_apiUrl}{Requests.Token}", request);
    var result = await response.EnsureSuccess<GetTokenResponse>();

    await Authenticate(result.Token, request.Email);
}

然后在页面上

public async Task ExecuteLogin()
{
    try
    {
        await AuthService.LoginAsync(_request);
        NavigationManager.NavigateTo("/");
    }
    catch (BadRequestException ex)
    {
        var response = ex.Response.Deserialize<ErrorsResponse>();
        Errors = response.Result.Messages;
    }
    catch (ForbiddenException ex)
    {
        var response = ex.Response.Deserialize<ErrorResponse>();
        Errors = new List<string> { response.Result.Message };
    }
}

【讨论】:

    猜你喜欢
    • 2020-11-26
    • 2016-08-09
    • 2021-04-09
    • 1970-01-01
    • 1970-01-01
    • 2017-11-29
    • 2018-07-21
    • 2015-11-24
    • 2017-08-27
    相关资源
    最近更新 更多