【问题标题】:How to access Httpclient headers in Blazor WASM Client如何在 Blazor WASM 客户端中访问 Httpclient 标头
【发布时间】:2021-03-31 16:58:15
【问题描述】:

我的客户端代码调用了一个 API,我试图从响应标头中获取返回的 ETag 值。如果我使用 Fiddler,我可以看到响应包含 ETag 标头,如果我使用 Postman 进行 API 调用,我可以看到 ETag 标头,但是无论我采用什么方法尝试检索代码中的标头,我得到的只是一个空。

本质上是 API 调用;

// 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

邮递员的回应是;

Postman response headers

我花了几个小时从网络上搜索和尝试示例,但无论我尝试什么,我都无法获得 ETag 标头。

使用下面的示例代码,我确实获得了前 2 个标头,如返回的 Postman 响应标头中所示,但不是 ETag 标头/值。

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

我正在使用 Visual Studio、Blazor 和 aspnetcore 5.0,我希望使用 IndexDB 生成 PWA,并使用 ETag 来减少数据下载。

任何有关如何获取 Etag 标头的帮助将不胜感激...

【问题讨论】:

    标签: c# blazor httpclient response-headers


    【解决方案1】:

    我和其他人有类似的问题。实际上,我们有 github 问题和关于这个问题的精彩讨论。我只是想与其他可能卡在同一点并访问堆栈溢出的人分享。

    问题链接(已关闭):

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

    引用讨论“您的 CORS 策略需要指定公开哪些标头。如果您希望客户端读取所有标头,您可以这样指定”

    示例(服务器端):

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

    【讨论】:

    • Dino,非常感谢这次更新,我差点放弃让 eTag 与 Blazor WASM 一起工作。但是,我只是按照您的说明添加了 .WithExposedHeaders("*") 并返回了 eTag 标头。我仍然有一个问题,为什么 Postman 在 API 服务器中没有该设置的情况下获取 eTag 标头,而 Blazor WASM 没有,但这可能是另一天......再次感谢......
    【解决方案2】:

    我创建了非常简单的控制台应用程序并使用它从 API 获取数据,我可以看到响应中返回了 ETag 值,但似乎无法使用 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

    我认为问题是由于该项目是 Blazor Web Assembly 项目,如果我创建简单的 .net 核心项目,则以下代码可以工作;

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

    但是 Blazor 中的相同代码却没有。

    【讨论】:

    • 你能用 .Content.Headers 比如response.Content.Headers.ETag 试试吗?
    • 问题在于 Blazor Web Assembly 项目,如果我创建控制台应用程序,则下面的代码有效;
    【解决方案3】:

    在响应消息对象上,可以直接访问 ETag 标头。

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

    【讨论】:

    • 感谢您的回复,我尝试了类似的选项,现在我已经尝试了您的代码,但返回的值仍然为空。我刚刚使用 restsharp 和 .net 4.7.2 制作了一个简单的控制台应用程序,并且可以看到所有标题,因此要创建简单的 aspnetcore 控制台应用程序来查看 httpclient 是否有效,将尝试版本 3.1 和 5.0
    猜你喜欢
    • 1970-01-01
    • 2021-02-27
    • 1970-01-01
    • 2021-02-24
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    • 1970-01-01
    • 2021-04-05
    相关资源
    最近更新 更多