2016-09-14 45 views
0

我有一个Web API,当传入的请求无效时,API会发回一个HttpStatusCode.BadRequest,并且API还会将一个CorrelationId添加到Response的HttpHeader中。类似下面从HttpRequestException中获取HttpHeaders?

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

在客户端IM使用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也斯蒂芬·克利里的文章here
尽管其建议,使异步一路下来,我这种情况下,客户端和API都彼此断开连接并且客户端是同步的。请注意,客户端的Process方法是同步方法。

回答

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(); 

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

+0

两个问题1>我们不必使用'ConfigureAwait(false)'来避免死锁。类似.'_httpClient.GetAsync(_appsettings.GetInProgressWorkunitsUrl).ConfigureAwait(false).GetAwaiter()。GetResult();'。见Stephen Cleary上面的文章。 2>当StatusCode确定时,如何获得响应字符串 – LP13

+0

对不起,更新了答案 – peco