HttpClient
.NET 4.5の新機能で HTTP HEAD リクエストを作成することは可能ですか? 私が見つけることができる唯一の方法は、、、GetAsync
およびです。-class でそれができることは知っていますが、モダンを使いたいです。DeleteAsync
PutAsync
PostAsync
HttpWebRequest
HttpClient
4 に答える
を使用して構築されSendAsync
た のインスタンスでメソッドを使用します。HttpRequestMessage
HttpMethod.Head
GetAsync
、、PostAsync
などは便利なラッパーSendAsync
です。HEAD
、などのあまり一般的でない HTTP メソッドOPTIONS
は、ラッパーを取得しません。
要するに:
client.SendAsync(new HttpRequestMessage(HttpMethod.Head, url))
TotalCount
Web API のGETメソッドから返された ATMを取得するために、これを行う必要がありました。
@Smig の回答を試したところ、Web API から次の応答が返されました。
MethodNotAllowed: プラグマ: no-cache X-SourceFiles: =?UTF-8?B?dfdsf Cache-Control: no-cache Date: 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
動詞を明示的に許可する必要があることがわかりました。
コード コメントによるインライン説明付きの完全なコードを次に示します。機密コードを削除しました。
私の 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()}");
}
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 ページング ヘッダー データを解析するためのヘルパー メソッド。
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;
}
}