【问题标题】:Get HttpHeaders from HttpRequestException?从 HttpRequestException 获取 HttpHeaders?
【发布时间】:2016-09-14 22:22:04
【问题描述】:

我有一个 Web API,当传入的请求无效时,API 会发回一个 HttpStatusCode.BadRequest,并且 API 还会将 CorrelationId 添加到响应的 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;
    }

我已经浏览过 SO 帖子 here 和 MSDN 文章 here 以及 Stephen Cleary 的文章 here
即使它建议一直进行异步,但在这种情况下,客户端和 API 都彼此断开连接,并且客户端是同步的。注意Client的Process方法是同步方法。

【问题讨论】:

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


    【解决方案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();.Result;,因为它不会引发 AggregateException,从而使代码更易于使用。

    如果您想将响应内容作为字符串读取,请执行以下操作:

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

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

    【讨论】:

    • 两个问题 1>我们不是必须使用ConfigureAwait(false) 来避免死锁吗?像 ._httpClient.GetAsync(_appsettings.GetInProgressWorkunitsUrl).ConfigureAwait(false).GetAwaiter().GetResult(); 之类的东西。请参阅上面的 Stephen Cleary 的文章。 2>StatusCode正常时如何获取响应字符串
    • 等待_httpClient.GetAsync(url).ConfigureAwait(false);
    猜你喜欢
    • 2015-09-23
    • 1970-01-01
    • 2014-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 2014-08-20
    • 1970-01-01
    相关资源
    最近更新 更多