web-dev-qa-db-fra.com

HTTP HEAD avec HttpClient dans .NET 4.5 et C #

Est-il possible de créer une requête HTTP HEAD avec la nouvelle HttpClient dans .NET 4.5? Les seules méthodes que je peux trouver sont GetAsync, DeleteAsync, PutAsync et PostAsync. Je sais que la classe HttpWebRequest- est capable de le faire, mais je veux utiliser la version moderne HttpClient.

47
The Wavelength

Utilisez la méthode SendAsync avec une instance de HttpRequestMessage qui a été construite à l'aide de HttpMethod.Head.

GetAsync, PostAsync, etc. sont enveloppes pratiques autour de SendAsync; les méthodes HTTP moins courantes telles que HEAD, OPTIONS, etc., n'obtiennent pas de wrapper.

78
Smigs

Vous pouvez également procéder comme suit pour récupérer uniquement les en-têtes:

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

Je devais faire cela, pour obtenir TotalCount des distributeurs automatiques que je retournais de mes API Web GET Méthode.

Lorsque j'ai essayé la réponse de @ Smig, j'ai reçu la réponse suivante de mon API Web.

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

J'ai dû m'appuyer sur la réponse de @ Smig pour que cela fonctionne correctement. J'ai découvert que les méthodes de l'API Web doivent autoriser explicitement le Http HEAD verbe en le spécifiant dans la méthode Action comme attribut.

Voici le code complet avec une explication en ligne au moyen de commentaires de code. J'ai supprimé le code sensible.

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

Dans l'API Web.

    // 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 Méthode d'assistance pour analyser les données d'en-tête de pagination.

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

}

5
Shiva