HttpClient.GetAsync возвращает HttpResponseMessage с нулевым заголовком

#asp.net-core #blazor #dotnet-httpclient #webassembly #response-headers

#asp.net-core #блейзор #dotnet-httpclient #webassembly #ответ-заголовки

Вопрос:

любитель net 5.0.

Я новичок в blazor и .net 5.0, я разрабатываю приложение с помощью blazor WebAssembly и WebAPI.

Есть два основных проекта: клиент, сервер.

Клиент — это Blazor WebAssembly, а сервер — проект контроллера WebAPI.

На стороне сервера, в контроллере, метод HttpGet, я добавляю значение в заголовок ответа:

         [HttpGet]
    public async Task<ActionResult<IList<Country>>> GetAsync([FromQuery] Pagination paginationDto)
    {
        /...
        httpContext.Response.Headers.Add("TotalPages", totalPages.ToString());
        //...
        IList<Country> = ...
        return resu<
    }
 

На странице razor проекта клиента вызовите api со следующим методом из общего calss:

         protected virtual async Task<PaginatedResponse<O>> GetAsync<O>(Pagination pagination)
    {
        HttpResponseMessage response = null;

        try
        {
            response = await httpClient.GetAsync(RequestUri);

            if (response.IsSuccessStatusCode)
            {
                try
                {
                    //This response Header always is null!
                    System.Console.WriteLine("response.Headers: "   response.Headers.ToString());

                    O result = await response.Content.ReadFromJsonAsync<O>();

                    var paginatedResponse = new PaginatedResponse<O>
                    {
                        Response = result,
                        TotalPages = totalPages
                    };

                    return paginatedResponse;
                }
    //...
        return defau<
    }
 

При вызове Api из postman результат и заголовок в порядке, и TotalPages есть.
В клиентском приложении результат в порядке, но заголовок равен нулю.

Любая информация спасет меня 😉

Заранее спасибо.

Комментарии:

1. Измените консоль отладки. Запись строки в: response.Headers["TotalPages"].ToString() я думаю, что вызов toString в списке не даст вам того, что вы ожидаете

2. спасибо за ответ, но он всегда равен нулю, как следует из ответа кода. Headers.getValues(«TotalPages»). FirstOrDefault() генерирует исключение, поскольку заголовки имеют значение null.

3. Видите ли вы заголовок в сетевом журнале браузера ?

4. Почему вы возвращаете a IList<Country> и количество в заголовке вместо a PaginatedResponse<Country> ?

5. Разве это помощь ? github.com/dotnet/runtime/issues/42179#issuecomment-692981038

Ответ №1:

Я думаю, вы слишком усложняете это, пытаясь использовать заголовки для передачи результата, который может быть передан более легко как часть содержимого. Вы даже вроде понимаете, что пытаетесь использовать a PaginatedResponse в клиенте Blazor.

Таким образом, вместо API, возвращающего только список, где-нибудь есть PaginatedResponse класс в общей библиотеке .. например

     /// <summary>
    /// Paged result class
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class PaginatedResponse<T>
    {

        public int TotalPages { get; set; }

        public int Page { get; set; }

        public List<T> Data { get; set; }

    }
 

Затем ваш API возвращает это

     [HttpGet]
    public async Task<ActionResult<PaginatedResponse<Country>>> GetAsync([FromQuery] Pagination paginationDto)
    {
        // ... query results here
        var result = new PaginatedResponse<Country>() 
        {
             Page = x, 
             TotalPages = totalPages,
             Data = countrylist  // from query
        };
        return resu<
    }
 

Затем ваш клиент Blazor может использовать тот же PaginatedResponse класс и просто использовать стандартный GetFromJsonAsync метод:

     var result = await Http.GetFromJsonAsync<PaginatedResponse<Country>>("yourApiUri");
 

Вот почему я люблю Blazor!

Комментарии:

1. Спасибо. он работает нормально, и я могу получить итоговые страницы из PaginationResponse, но я хочу знать, почему нельзя получить информацию из заголовка ответа? или почему не удается получить доступ к заголовку из кода, в чем ошибка в моем коде?

2. @mRizvandi Я пытался использовать .GetAsync для запроса API, но я не думаю, что он работает правильно, поэтому вы вряд ли это исправите. Если вы отчаянно хотите пойти по этому пути, я не могу помочь

Ответ №2:

Это именно тот ответ на вопрос, как искать ответ:

в проекте сервера, в startup.cs, в методе ConfigureServices добавьте следующий код для CORS или обновите свое правило CORS:

                 services.AddCors(options => options.AddPolicy(name: "WebApiProjectName or somthing", builder =>
        {
            builder.WithOrigins("http://localhost:xxxx") //xxxxx is server port
               .AllowAnyMethod()
               .AllowAnyHeader()
               //.AllowCredentials() // its optional for this answer
               .WithExposedHeaders("*"); // this is the code you need!
        }));