英文:
How to solve the “System.InvalidOperationException: The given header was not found.” exception in Blazor WASM Client
问题
In my Blazor WASM client project, I need to call an API and put the value of "X-Pagination" in its header, unfortunately, when I call this API I get this exception in the browser console:
    WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: The given header was not found.
   System.InvalidOperationException: The given header was not found.
   at System.Net.Http.Headers.HttpHeaders.GetValues(HeaderDescriptor descriptor)
   at System.Net.Http.Headers.HttpHeaders.GetValues(String name)
My API:
    [HttpPost]
    public async Task<ApiResult<PagedList<ReceiptDto>>> GetAll(Pagable pagable, CancellationToken cancellationToken)
    {
        Guid? userId = User.Identity.GetGuidUserId();
        GetReceiptsQuery query = new(pagable, (Guid)userId);
        var result = await _mediator.Send(query, cancellationToken);
        Response.Headers.Add("X-Pagination", JsonConvert.SerializeObject(result.Data.MetaData));
        return result;
    }
Also I added .AllowAnyHeader() method to the CORS policy API in the startup class:
   services.AddCors(
            options =>
            {
                options.AddDefaultPolicy(builder =>
                {
                    builder.WithOrigins(
                        "https://localhost:44366/",
                        "http://localhost:44366/")
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowAnyOrigin();
                });
            })
In my method in wasm client, I call my httpclient and get the values of header:
    public async Task<PagingResponse<ReceiptDto>> GetReceipts(Pagable pagable)
    {
        HttpResponseMessage response = await _client.PostAsJsonAsync("v1/Users/Receipts/GetAll", pagable);
        if (!response.IsSuccessStatusCode)
        {
            throw new ApplicationException(response.Content.ToString());
        }
        var result = await response.Content.ReadAsAsync<ApiResult<List<ReceiptDto>>>();
        if (!result.IsSuccess)
        {
            throw new ApplicationException(result.Message);
        }
        PagingResponse<ReceiptDto> pagingResponse = new()
        {
            Items = result.Data,
            MetaData = JsonSerializer.Deserialize<MetaData>(response.Headers.GetValues("X-Pagination").First(), _options)
        };
        return pagingResponse;
    }
Whereas when I call this API in Postman or Swagger there is no problem:
but as I said at the beginning of my question, when I call this API in the Blazor WASM client, I get the above error.
I encounter an error while calling API, I shared it to solve it.
英文:
In my Blazor WASM client project, I need to call an API and put the value of "X-Pagination" in its header, unfortunately, when I call this API I get this exception in the browser console:
    WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: The given header was not found.
   System.InvalidOperationException: The given header was not found.
   at System.Net.Http.Headers.HttpHeaders.GetValues(HeaderDescriptor descriptor)
   at System.Net.Http.Headers.HttpHeaders.GetValues(String name)
My API:
    [HttpPost]
    public async Task<ApiResult<PagedList<ReceiptDto>>> GetAll(Pagable pagable, CancellationToken cancellationToken)
    {
        Guid? userId = User.Identity.GetGuidUserId();
        GetReceiptsQuery query = new(pagable, (Guid)userId);
        var result = await _mediator.Send(query, cancellationToken);
        Response.Headers.Add("X-Pagination", JsonConvert.SerializeObject(result.Data.MetaData));
        return result;
    }
Also I added .AllowAnyHeader() method to the CORS policy API in the startup class:
   services.AddCors(
            options =>
            {
                options.AddDefaultPolicy(builder =>
                {
                    builder.WithOrigins(
                        "https://localhost:44366/",
                        "http://localhost:44366/")
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowAnyOrigin();
                });
            })
In my method in wasm client, I call my httpclient and get the values of header :
    public async Task<PagingResponse<ReceiptDto>> GetReceipts(Pagable pagable)
    {
        HttpResponseMessage response = await _client.PostAsJsonAsync("v1/Users/Receipts/GetAll", pagable);
        if (!response.IsSuccessStatusCode)
        {
            throw new ApplicationException(response.Content.ToString());
        }
        var result = await response.Content.ReadAsAsync<ApiResult<List<ReceiptDto>>>();
        if (!result.IsSuccess)
        {
            throw new ApplicationException(result.Message);
        }
        PagingResponse<ReceiptDto> pagingResponse = new()
        {
            Items = result.Data,
            MetaData = JsonSerializer.Deserialize<MetaData>(response.Headers.GetValues("X- Pagination").First(), _options)
        };
        return pagingResponse;
    }
Whereas when I call this API in Postman or Swagger there is no problem :

but as I said at the beginning of my question, when I call this API in the Blazor WASM client, I get the above error.
I encounter an error while calling API, I shared it to solve it.
答案1
得分: 2
我最终意识到API的CORS策略应该指定哪些标头被暴露,因此我解决了异常并在API启动类中更改了CORS设置如下:
services.AddCors(
    options =>
    {
        options.AddDefaultPolicy(builder =>
        {
            builder.WithOrigins(
                "https://localhost:44366/",
                "http://localhost:44366/")
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowAnyOrigin()
            .WithExposedHeaders("X-Pagination");  // 这一行很重要
        });
    })
英文:
I finally realized that the API CORS policy should specify what headers are exposed, so I resolved the exception and changed the CORS settings in the API startup class as below:
services.AddCors(
            options =>
            {
                options.AddDefaultPolicy(builder =>
                {
                    builder.WithOrigins(
                        "https://localhost:44366/",
                        "http://localhost:44366/")
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowAnyOrigin()
                    .WithExposedHeaders("X-Pagination");  // this line is important
                });
            })
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论