从HttpRequestException获取HttpHeaders?

时间:2016-09-14 22:22:05

标签: asp.net-web-api async-await

我有一个Web API,当传入请求无效时,API会发回一个HttpStatusCode.BadRequest,API也会将CorrelationId添加到Response的HttpHeader中。像下面的东西

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."
            };
       }
    }
}

在客户端我使用HttpClient访问API。我不确定客户端如何在这里检索HttpStatusCode和HttpHeader。这是我的客户代码

    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;
    }

我已经浏览过帖子here和MSDN文章here以及Stephen Cleary的文章here
尽管建议将异步一直向下,但我的情况是Client和API都彼此断开连接,并且客户端是同步的。请注意,Client的Process方法是同步方法。

1 个答案:

答案 0 :(得分:1)

像这样:

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;
}

另请注意,建议执行.GetAwaiter().GetResult(); vs .Result;,因为它使代码更易于使用,因为它不会抛出AggregateException

如果您想以字符串形式阅读响应内容,请执行以下操作:

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

如果你想让你的代码异步,你应该使用async / await关键字并跳过.GetAwaiter().GetResult();