简体   繁体   中英

.NET Core WebApi Get HttpClient Error Message

I am trying to display the relevant error message returned from a Web API when using HttpClient.PostJsonAsync<T>() .

In my Web API, for example on a failed login I would return a 401 unauthorized exception with the message in the body with an error handling middleware;

public class HttpErrorHandlerMiddleware
{
    private readonly RequestDelegate _next;

    public HttpErrorHandlerMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (HttpStatusCodeException exception)
        {
            if (!context.Response.HasStarted)
            {
                context.Response.StatusCode = (int)exception.StatusCode;
                context.Response.Headers.Clear();
                await context.Response.WriteAsync(exception.Message);
            }
        }
    }
}

// Extension method used to add the middleware to the HTTP request pipeline.
public static class HttpErrorHandlerMiddlewareExtensions
{
    public static IApplicationBuilder UseHttpErrorHandlerMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<HttpErrorHandlerMiddleware>();
    }
}

Then in Postman this is displayed with the message eg 'Invalid UserName or Password', 'User is Locked out.', etc.

However, when I try to catch the error on the client side, eg

try
{
    var result = await _httpClient.PostJsonAsync<LoginResponse>("api/login", loginModel);

    /* Removed for brevity */
}
catch(Exception ex)
{
     return new LoginResponse { Success = false, Error = ex.Message };
}

The error returned is always 'Response status code does not indicate success: 401 (Unauthorized).'

How would I get the detail of the error from the return of the PostJsonAsync<T> please?

401 is a validate response, and it would not be captured in HttpErrorHandlerMiddleware .

I am not sure how you implement 401 and PostJsonAsync . Here is a working demo for you:

  1. Controller Action

    [HttpPost] public IActionResult Login(LoginModel loginModel) { return StatusCode(401, new LoginResponse { Success = false, Error = "Invalid User Name and Password" }); }
  2. HttpClient Request

    public async Task<LoginResponse> Test(LoginModel loginModel) { var _httpClient = new HttpClient(); var result = await _httpClient.PostAsJsonAsync<LoginModel>("https://localhost:44322/api/values/login", loginModel); return await result.Content.ReadAsAsync<LoginResponse>(); }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM