0

I have a Web API, When the incoming request is not valid then the API sends back a HttpStatusCode.BadRequest and API would also add a CorrelationId into Response's HttpHeader. Something like below

public class ValidateRequestAttribute : ActionFilterAttribute
{
    public ValidateRequestAttribute()
    {

    }
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (context.ModelState.IsValid == false)
        {               
            context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
            context.HttpContext.Response.Headers.Add("x-correlationid", "someid");
            context.Result = new ContentResult()
            {
                Content = "bad request."
            };
       }
    }
}

On client side im using HttpClient to access the API. I am not sure how client would retrieve HttpStatusCode and HttpHeader here. Here is my client code

    public bool Process(url)
    {
        bool result = false;

        try
        {
            Task.Run(async () => await _httpClient.GetStringAsync(url).ConfigureAwait(false)).Result;
        }
        catch (Exception ex)
        {
            if(ex is AggregateException)
            {
                var aggregateException = ex as AggregateException;
                foreach(var innerException in aggregateException.InnerExceptions)
                {
                    if (innerException is HttpRequestException)
                    {
                        var httpRequestException = innerException as HttpRequestException;

                        // how do i get StatusCode and HttpHeader values here??
                    }
                }
            }       
        }

        return result;
    }

I have already gone through SO post here and MSDN article here and also Stephen Cleary's article here
Even though its recommended to make async all the way down, I this case Client and API are both disconnected from each other and client is synchronous. Note that Client's Process method is synchronous method.

Community
  • 1
  • 1
LP13
  • 30,567
  • 53
  • 217
  • 400

1 Answers1

1

Like this:

public bool Process(string url)
{
    var result = _httpClient.GetAsync(url).ConfigureAwait(false).GetAwaiter().GetResult();

    if (result.StatusCode == HttpStatusCode.BadRequest)
    {
        IEnumerable<string> values;
        if (result.Headers.TryGetValues("x-correlationid", out values))
        {
            // Should print out "someid"
            Console.WriteLine(values.First());
        }
    }

    return result.IsSuccessStatusCode;
}

Also note that doing .GetAwaiter().GetResult(); vs .Result; is recommended since it makes the code easier to work with because it does not throw an AggregateException.

If you want to read the response content as a string just do:

var content = result.Content.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();

If you want to make your code async though you should use the async/await keyword and skip the .GetAwaiter().GetResult();.

peco
  • 3,890
  • 1
  • 20
  • 27
  • Two questions 1>don't we have to use `ConfigureAwait(false)` to avoid dead lock. Something like .`_httpClient.GetAsync(_appsettings.GetInProgressWorkunitsUrl).ConfigureAwait(false).GetAwaiter().GetResult();` . See Stephen Cleary's article above. 2>How do I get response string when StatusCode is OK – LP13 Sep 15 '16 at 16:00
  • await _httpClient.GetAsync(url).ConfigureAwait(false); – Rob Sedgwick Jan 20 '21 at 11:55