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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16416699/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 00:58:03  来源:igfitidea点击:

HTTP HEAD request with HttpClient in .NET 4.5 and C#

c#.nethttprequest.net-4.5

提问by The Wavelength

Is it possible to create a HTTP HEAD request with the new HttpClientin .NET 4.5? The only methods I can find are GetAsync, DeleteAsync, PutAsyncand PostAsync. I know that the HttpWebRequest-class is able to do that, but I want to use the modern HttpClient.

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

采纳答案by Smigs

Use the SendAsyncmethod with an instance of HttpRequestMessagethat was constructed using HttpMethod.Head.

将该SendAsync方法与HttpRequestMessage使用 构造的实例一起使用HttpMethod.Head

GetAsync, PostAsync, etc are convenient wrappersaround SendAsync; the less common HTTP methods such as HEAD, OPTIONS, etc, don't get a wrapper.

GetAsyncPostAsync等是方便的包装周围SendAsync; 不太常见的HTTP方法,如HEADOPTIONS等,没有得到的包装。

回答by Shiva

I needed to do this, to get TotalCountof ATMs that I was returning from my Web API's GETMethod.

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

When I tried @Smig's answer I got the following Response from my Web API.

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

MethodNotAllowed : Pragma: no-cache X-SourceFiles: =?UTF-8?B?dfdsf Cache-Control: no-cache Date: Wed, 22 Mar 2017 20:42:57 GMT Server: Microsoft-IIS/10.0 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET

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

Had to built upon @Smig's answer to get this working successfully. I found out that the Web API methods needs to explicitly allow the Http HEADverb by specifying it in the Actionmethod as an Attribute.

必须建立在@Smig 的回答上才能成功完成这项工作。我发现 Web API 方法需要Http HEAD通过在Action方法中将动词指定为属性来明确允许该动词。

Here's the complete code with inline explanation by way of code comments. I've removed the sensitive code.

这是通过代码注释的方式内联解释的完整代码。我已经删除了敏感代码。

In my Web Client:

在我的 Web 客户端中:

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

In the Web API.

在 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 method for parsing the paging header data.

FindAndParsePagingInfo 解析分页头数据的辅助方法。

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

}

}

回答by rothschild86

You may also do as follows to fetch just the headers:

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

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