SteveW
SteveW

Reputation: 43

How to access Httpclient headers in Blazor WASM Client

My client code makes call to an API and I'm trying to get the returned ETag value from the response headers. If I use Fiddler I can see the response contains the ETag header and if I make API call using Postman I can see the ETag header, but no matter what approach I take to try and retrieve the headers in my code all I get returned is a null.

Essentially the API call is;

// create request object
var request = new HttpRequestMessage(HttpMethod.Get, url);
// add authorization header
request.Headers.Authorization = new AuthenticationHeaderValue("bearer", await GetBearerToken());
// send request
HttpResponseMessage response = await _client.SendAsync(request);

Fiddler Response Header showing Etag

The Postman response is;

Postman response headers

I've spent hours searching and trying examples from web, but no matter what I try I can't get the the ETag header.

Using the example code below I do get the first 2 headers as shown in the Postman response headers returned but not the ETag header / value.

String allResponseHeaders = Enumerable
    .Empty<(String name, String value)>()
    .Concat(
    response.Headers
    .SelectMany(kvp => kvp.Value
    .Select(v => (name: kvp.Key, value: v))
    ))
    .Concat(
    response.Content.Headers
    .SelectMany(kvp => kvp.Value
    .Select(v => (name: kvp.Key, value: v))
    ))
   .Aggregate(
   seed: new StringBuilder(),
   func: (sb, pair) => sb.Append(pair.name).Append(": ").Append(pair.value).AppendLine(),
   resultSelector: sb => sb.ToString()
   );

I'm using Visual Studio, Blazor and aspnetcore 5.0 and I'm looking to generate an PWA with IndexDB and use ETag's to reduce data downloads.

Any help on how to get to the Etag header will be much appreciated...

Upvotes: 3

Views: 5982

Answers (3)

Dino Lozina
Dino Lozina

Reputation: 71

I had similar issue like other people. Actually we have github issue and great discussion that was open on this issue. I just want to share like with other people that are maybe stuck at same point and visit stack overflow.

Link for issue (closed):

https://github.com/dotnet/runtime/issues/42179

Quote from discussion "Your CORS policy needs to specify what headers are exposed. If you would like the client to read all headers, you can specify it as so"

Example(Server side):

services.AddCors(options =>
{
    options.AddPolicy("Open", builder => builder
        .AllowAnyOrigin()
        .AllowAnyHeader()
        .AllowAnyMethod()
        .WithExposedHeaders("*")); // this is the important part!
});

Upvotes: 7

SteveW
SteveW

Reputation: 43

I created very simple console app and used that to GET data from API, I can see that the ETag value is being returned in the response but can't seem to simply extract the value in code, using response.Headers.Etag.

using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace SimpleAPIClient
{

    class Program
    {
        private static readonly HttpClient client = new HttpClient();

        static async Task Main(string[] args)
        {

            var request = new HttpRequestMessage(HttpMethod.Get, "https://localhost:44338/api/headers/3");
            request.Headers.Authorization = new AuthenticationHeaderValue("bearer", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbkBjb250cmEtc29mdC5jb20iLCJqdGkiOiI4NjgyMmQ1YS1iNTQ3LTRlMjItYmQ3NS0wNDlkZmE5MTMzZmUiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjVkODExZmY1LTgyY2QtNDY2NC05ODkzLTZmNGRjMDU0YzFmNSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6IkFkbWluaXN0cmF0b3IiLCJleHAiOjE2MDgzNTU0MTEsImlzcyI6ImNvbnRyYS1zb2Z0LmNvbSIsImF1ZCI6ImNvbnRyYS1zb2Z0LmNvbSJ9.w_CSstMZkFFn0DcMlcPNNm_Nr0idzHPo6I2hRjEUglQ");
            HttpResponseMessage response = await client.SendAsync(request);

            var etag = response.Headers.ETag;

            int i = 0;
        }

    }
}

VS Breakpoint shows ETag data

I believe the issue is due to the project being a Blazor Web Assembly project, if I create simple .net core project then the following code works;

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiO");
Task<HttpResponseMessage> s = client.GetAsync("https://localhost:44338/api/headers/3");
HttpResponseMessage nresponse2 = await s;
var etag2 = nresponse2.Headers.FirstOrDefault(i => i.Key == "ETag").Value.FirstOrDefault();

However the same code in Blazor does not.

Upvotes: 1

Just the benno
Just the benno

Reputation: 2601

On the response message object, you can access the ETag header directly.

// create request object
var request = new HttpRequestMessage(HttpMethod.Get, url);
// add authorization header
request.Headers.Authorization = new AuthenticationHeaderValue("bearer", await GetBearerToken());
// send request
HttpResponseMessage response = await _client.SendAsync(request);

//read the response headers. The ETag is already a "known" header and is easily accessible via a property
EntityTagHeaderValue etagHeader = response.Headers.ETag;

Upvotes: 0

Related Questions