【问题标题】:.Net Core Handle exceptions that returned from web api.Net Core 处理从 web api 返回的异常
【发布时间】:2020-12-03 17:20:28
【问题描述】:

我使用 .Net 5.0 作为后端,使用 .Net 5.0 作为客户端。

我想知道如何在客户端处理从 web api 返回的异常并将它们显示给客户端。

异常的api结果如下:

{
  "Version": "1.0",
  "StatusCode": 500,
  "ErrorMessage": "User not found!"
}

如何在客户端全局处理此类异常(使用.Net Core MVC)?

【问题讨论】:

  • @NishānWickramarathna 我已经检查过了,但我想在客户端处理从 web api 返回的异常。
  • 你的客户端框架/库是什么?角度或反应?或其他
  • @mohanoorani 我在客户端使用 .Net Core。

标签: asp.net .net asp.net-mvc asp.net-core .net-5


【解决方案1】:

根据您的描述,我建议您可以在服务器端使用 try catch 来捕获异常并作为 json 响应返回。

在客户端,您可以使用反序列化响应并创建一个名为 Error 的新视图来显示响应消息。

更多细节,您可以参考以下代码:

错误类别:

public class APIError
{
    public string Version { get; set; }
    public string StatusCode { get; set; }
    public string ErrorMessage { get; set; }
}

API:

[HttpGet]
public IActionResult Get()
{
    try
    {
        throw new Exception("UserNotFound");
    }
    catch (Exception e)
    {

        return Ok(new APIError { Version="1.0", ErrorMessage=e.Message, StatusCode="500" });
    }


}

应用:

       var request = new HttpRequestMessage(HttpMethod.Get,
"https://localhost:44371/weatherforecast");


        var client = _clientFactory.CreateClient();

        var response = await client.SendAsync(request);

        if (response.IsSuccessStatusCode)
        {
             var responseStream = await response.Content.ReadAsStringAsync();
            APIError re = JsonSerializer.Deserialize<APIError>(responseStream, new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true,
            });

            if (re.StatusCode == "500")
            {

                return View("Error", new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier, Version = re.Version, StatusCode = re.StatusCode, ErrorMessage = re.ErrorMessage });

            }


        }
        else
        {
            // Hanlde if request failed issue
        }

注意:我新建了一个错误视图,你可以自己创建或者修改默认的错误视图。

错误视图模型:

public class ErrorViewModel
{
    public string RequestId { get; set; }

    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);

    public string Version { get; set; }
    public string StatusCode { get; set; }
    public string ErrorMessage { get; set; }
}

错误视图:

@model ErrorViewModel
@{
    ViewData["Title"] = "Error";
}

<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>

@if (Model.ShowRequestId)
{
    <p>
        <strong>Request ID:</strong> <code>@Model.RequestId</code>
    </p>
}

<h3>@Model.StatusCode</h3>
<p>
    @Model.ErrorMessage
</p>
 

结果:

【讨论】:

    【解决方案2】:

    如果您不想在后端使用异常,您可以将 http 状态代码发送给客户端。这是一个通过服务访问外部 api 并将该状态返回给后端控制器的示例。然后,您只需通过客户端获取此结果。如果需要,您也可以只向客户端发送完整的 http 响应,而不是仅发送 HttpStatusCode。

    这里稍微详细一点:https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client

    //Backend Service..
    private const string baseUrl = "https://api/somecrazyapi/";
    
    public async Task<HttpStatusCode> GetUserStatusAsync(string userId)
    {
        var httpResponse = await client.GetAsync(baseUrl + "userId");
        return httpResponse.StatusCode;
    }
    
    //Backend Controller
    [ApiController]
    [Route("[controller]")]
    public class UserController
    {
        private readonly IUserService service;
        public UserController(IUserService service)
        {
            this.service = service;
        }
    
        ......
    
        [HttpGet("{userId}")]
        public HttpStatusCode GetUserStatus(string userId)
        {
            return service.GetUserStatusAsync(userId).Result;
        }
    }
    

    【讨论】:

    • 如果后端遇到异常我将如何在客户端处理?
    猜你喜欢
    • 1970-01-01
    • 2016-12-02
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 2019-04-22
    • 2019-10-27
    相关资源
    最近更新 更多