Reputation: 3931
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?
Upvotes: 0
Views: 4985
Reputation: 29966
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:
Controller Action
[HttpPost]
public IActionResult Login(LoginModel loginModel)
{
return StatusCode(401, new LoginResponse {
Success = false,
Error = "Invalid User Name and Password"
});
}
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>();
}
Upvotes: 3