.NET 4.5 和 C# 中带有 HttpClient 的 HTTP HEAD 请求

Posted

技术标签:

【中文标题】.NET 4.5 和 C# 中带有 HttpClient 的 HTTP HEAD 请求【英文标题】:HTTP HEAD request with HttpClient in .NET 4.5 and C# 【发布时间】:2013-05-07 10:25:19 【问题描述】:

是否可以在 .NET 4.5 中使用新的 HttpClient 创建 HTTP HEAD 请求?我能找到的唯一方法是GetAsyncDeleteAsyncPutAsyncPostAsync。我知道HttpWebRequest-class 可以做到这一点,但我想使用现代的HttpClient

【问题讨论】:

Adding Http Headers to HttpClient (ASP.NET Web API)的可能重复 这不是重复的。我只想读取我发出的请求的响应标头,这可以使用 HTTP HEAD 请求。和你提到的线程完全没有关系。 【参考方案1】:

SendAsync 方法与使用HttpMethod.Head 构造的HttpRequestMessage 实例结合使用。

GetAsyncPostAsync 等是convenient wrappers 在SendAsync 附近;不太常见的 HTTP 方法,例如 HEADOPTIONS 等,没有包装器。

简而言之:

client.SendAsync(new HttpRequestMessage(HttpMethod.Head, url))

【讨论】:

【参考方案2】:

您还可以执行以下操作来仅获取标题:

this.GetAsync($"http://url.com", HttpCompletionOption.ResponseHeadersRead).Result;

【讨论】:

这种方法的美妙之处在于它即使目标服务器明确禁止HEAD请求(例如亚马逊AWS)也能工作。 从代码的角度来看,我喜欢这个选项,Ian 的评论也是一个优势。但是我实现了这个,Smigs 的答案和 Smigs 的答案执行得更快......当然,我的 Urls 指向 30-100MB 的文件,这可能与此有关。但是这个答案发出的是 GET 请求而不是 HEAD,所以请记住这一点。 我得到一个“不允许的方法”【参考方案3】:

我需要这样做,以获取我从 Web API 的 GET 方法返回的 TotalCount 个 ATM。

当我尝试@Smig 的回答时,我从我的 Web API 得到以下响应。

MethodNotAllowed : Pragma: no-cache X-SourceFiles: =?UTF-8?B?dfdsf Cache-Control: no-cache 日期: Wed, 22 Mar 2017 20:42:57 GMT 服务器: Microsoft-IIS/10.0 X-AspNet-版本:4.0.30319 X-Powered-By:ASP.NET

必须以@Smig 的回答为基础才能成功运行。我发现 Web API 方法需要通过在 Action 方法中将其指定为属性来明确允许 Http HEAD 动词。

这是通过代码 cmets 进行内联解释的完整代码。我已经删除了敏感代码。

在我的网络客户端中:

        HttpClient client = new HttpClient();

        // set the base host address for the Api (comes from Web.Config)
        client.BaseAddress = new Uri(ConfigurationManager.AppSettings.Get("ApiBase"));
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add( 
          new MediaTypeWithQualityHeaderValue("application/json"));

        // Construct the HEAD only needed request. Note that I am requesting
        //  only the 1st page and 1st record from my API's endpoint.
        HttpRequestMessage request = new HttpRequestMessage(
          HttpMethod.Head, 
          "api/atms?page=1&pagesize=1");

        HttpResponseMessage response = await client.SendAsync(request);

        // FindAndParsePagingInfo is a simple helper I wrote that parses the 
        // json in the Header and populates a PagingInfo poco that contains 
        // paging info like CurrentPage, TotalPages, and TotalCount, which 
        // is the total number of records in the ATMs table.
        // The source code is pasted separately in this answer.
        var pagingInfoForAtms = HeaderParser.FindAndParsePagingInfo(response.Headers);

        if (response.IsSuccessStatusCode)
            // This for testing only. pagingInfoForAtms.TotalCount correctly
            //  contained the record count
            return Content($"# of ATMs pagingInfoForAtms.TotalCount");

            // if request failed, execution will come through to this line 
            // and display the response status code and message. This is how
            //  I found out that I had to specify the HttpHead attribute.
            return Content($"response.StatusCode : response.Headers.ToString()");
        

在 Web API 中。

    // Specify the HttpHead attribute to avoid getting the MethodNotAllowed error.
    [HttpGet, HttpHead]
    [Route("Atms", Name = "AtmsList")]
    public IHttpActionResult Get(string sort="id", int page = 1, int pageSize = 5)
    
        try
        
            // get data from repository
            var atms =  _atmRepository.GetAll().AsQueryable().ApplySort(sort);
            // ... do some code to construct pagingInfo etc.
            // .......
            // set paging info in header.
            HttpContext.Current.Response.Headers.Add(
              "X-Pagination", JsonConvert.SerializeObject(paginationHeader));
            // ...
            return Ok(pagedAtms));
        
        catch (Exception exception)
        
            //... log and return 500 error
        
    

FindAndParsePagingInfo Helper 方法,用于解析分页头数据。

public static class HeaderParser

public static PagingInfo FindAndParsePagingInfo(HttpResponseHeaders responseHeaders)

    // find the "X-Pagination" info in header
    if (responseHeaders.Contains("X-Pagination"))
    
        var xPag = responseHeaders.First(ph => ph.Key == "X-Pagination").Value;

        // parse the value - this is a JSON-string.
        return JsonConvert.DeserializeObject<PagingInfo>(xPag.First());
    

    return null;


public static string GetSingleHeaderValue(HttpResponseHeaders responseHeaders, 
    string keyName)

    if (responseHeaders.Contains(keyName))
        return responseHeaders.First(ph => ph.Key == keyName).Value.First();

    return null;

【讨论】:

@Kiquenet 嗨,我用HeaderParser.FindAndParsePagingInfo 源更新了答案。 方法IHttpActionResult Get中的paginationHeader变量是什么?【参考方案4】:

解决了

 var result = await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, url));

【讨论】:

以上是关于.NET 4.5 和 C# 中带有 HttpClient 的 HTTP HEAD 请求的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# (.NET 4.5) 中为 HttpClient.GetAsync(URI) 创建回调?

在 C# .NET 4.5 中使用 SAML 2.0

使用 C# .Net 4.5 的高效且可扩展的连接 TCP Windows 服务

C# .NET 4.5 将多个文件添加到压缩包中

C# sapnco支持.net 4.5了,真是个意外的发现

c# .net 3.5 4.0 4.5 5.0 6.0各个版本新特性战略规划总结转载