0

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 e.g. 'Invalid UserName or Password', 'User is Locked out.', etc.

However, when I try to catch the error on the client side, e.g.

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?

4
  • 1
    because it doesn't consider your messasge is the exception reason. You can always return a message "Everything was done perfectly" with your 401. To get the message, read the body returned from client Commented Aug 20, 2019 at 15:18
  • @TuyenPham how would I read the body from the return exception from PostJsonAsync<T> please? Commented Aug 20, 2019 at 15:26
  • intead of PostJsonAsync, you can use PostAsync, which allow you to read the content when there is an exception: stackoverflow.com/a/39414248/1560697 Commented Aug 20, 2019 at 15:29
  • How did you return 401 with Invalid UserName or Password in the body? What is PostJsonAsync? Commented Aug 21, 2019 at 2:33

1 Answer 1

3

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>();
    }
    
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.