hTTPResponse.Content.ReadAsStringAsync() 上的空消息。第一个 foreach 循环后的结果

Null message on hTTPResponse.Content.ReadAsStringAsync().Result after 1st foreach loop

我在 foreach 循环中调用 HttpClient getAsync 时遇到空结果消息的问题。

我需要迭代一个对象列表以获得值以通过 HttpClient 调用 API。在第一个循环之后,HttpResponseMessage 的 result() 出现空消息。

我试过了 CacheControl.NoCache = true。没用。

public async Task<List<Common.ProgressResponse>> RunAsync()
{
    List<Response> ListOfResponses = new List<Responses>();

    try
    {
        _client.BaseAddress = new Uri([URL]);
        _client.DefaultRequestHeaders.Accept.Clear();
        _client.DefaultRequestHeaders.Clear();
        _client.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue() { NoCache = true };
        _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        _client.DefaultRequestHeaders.Add([KEY], [VALUE]);

        ListOfResponses = await SomeFunction();

    }
    catch (Exception ex)
    {
        //Exceptions here...
    }
    return ListOfResponses;
}


private async Task<List<ListOfResponses>> SomeFunction()
{
    List<Response> responses = new List<Response>();
    string aPISuffix = string.Format("{0}/{1}", [APISUFFIX1], [APISUFFIX2]);

    foreach (Object obj in ListOfObject)
    {
        _client.DefaultRequestHeaders.Add("Param1", obj.Param1);
        if (!string.IsNullOrEmpty(obj.Param2))
            _client.DefaultRequestHeaders.Add("Param2", obj.Param2);

        Response response = new Response();


/*This is where the issue is .begin.*/
        HttpResponseMessage hTTPResponse = await _client.GetAsync(aPISuffix).ConfigureAwait(false);
        string result = hTTPResponse.Content.ReadAsStringAsync().Result;
/*This is where the issue is .end.*/


        if (hTTPResponse.IsSuccessStatusCode)
        {
            response = [Code here...]
            //Codes here...
        }

        responses.Add(response);
    }

    return responses;
}

开启:'string result = hTTPResponse.Content.ReadAsStringAsync().Result;' 我希望结果消息在遍历 ListOfObjects 时会有值。

更新:根据评论

首先,我通常尽量避免在任务中使用 .Result。我也不认为添加缓存 headers 是问题,因为您正在进行服务器到服务器的调用。

我经常做的一件事是在尝试阅读之前评估回复。我也更喜欢使用 HttpRequestMessage,这样我就可以管理它的处理。

这是一个演示如何调用的简单示例:

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

namespace Testing
{
    class Program
    {
        static void Main(string[] args)
        {
            TestAsync().Wait();
        }

        static async Task TestAsync()
        {
            var urls = new string[]
            {
                "https://whosebug.com/questions/57084989/null-message-on-httpresponse-content-readasstringasync-result-after-1st-foreac",
                "https://whosebug.com/users/2025711/rogala"
            };

            using (var httpClient = new HttpClient())
            {
                foreach (var url in urls)
                {
                    using (var request = new HttpRequestMessage(HttpMethod.Get, url))
                    {
                        Console.WriteLine($"Request: {url}".PadLeft(5,'*').PadRight(5, '*'));
                        var response = await httpClient.SendAsync(request)
                            .ConfigureAwait(false);

                        if (response.IsSuccessStatusCode)
                        {
                            var body = await response.Content.ReadAsStringAsync()
                            .ConfigureAwait(false);
                            Console.WriteLine($"{body.Length}{Environment.NewLine}");
                        }
                        else
                        {
                            Console.WriteLine($"*Bad request: {response.StatusCode}");
                        }
                        
                    }
                }
            }

            Console.ReadKey();
        }
    }
}

要记住的另一件事是套接字耗尽。如果此代码在服务器上 运行ning,那么一旦您的服务获得一些负载,您将 运行 陷入套接字耗尽状态。我强烈建议使用 HttpClientFactory 来处理 HttpClients。

关于为什么内容字符串为空,可能是因为服务器没有return内容,这可能是服务器问题。服务器也可能对您进行了限制,导致没有内容。我建议查看 Polly 来处理某些响应代码。

解决了...我将 .DefaultRequestHeaders 值移动到 foreach() 循环中。 我怀疑他们在每次循环迭代时都在堆积。我必须清除它们并在 GetAsync()

之前设置它们

此处更新代码:

public async Task<List<Common.ProgressResponse>> RunAsync()
{
    List<Response> ListOfResponses = new List<Responses>();

    try
    {
        _client.BaseAddress = new Uri([URL]);
        ListOfResponses = await SomeFunction();

    }
    catch (Exception ex)
    {
        //Exceptions here...
    }
    return ListOfResponses;
}


private async Task<List<ListOfResponses>> SomeFunction()
{
    List<Response> responses = new List<Response>();
    string aPISuffix = string.Format("{0}/{1}", [APISUFFIX1], [APISUFFIX2]);

    foreach (Object obj in ListOfObject)
    {
        /*Moved Code .begin.*/
        _client.DefaultRequestHeaders.Accept.Clear();
        _client.DefaultRequestHeaders.Clear();
        _client.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue() { NoCache = true };
        _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        _client.DefaultRequestHeaders.Add([KEY], [VALUE]);      

        /*Moved Code .end.*/

        _client.DefaultRequestHeaders.Add("Param1", obj.Param1);
        if (!string.IsNullOrEmpty(obj.Param2))
            _client.DefaultRequestHeaders.Add("Param2", obj.Param2);

        Response response = new Response();
        HttpResponseMessage hTTPResponse = await _client.GetAsync(aPISuffix).ConfigureAwait(false);

        if (hTTPResponse.IsSuccessStatusCode)
        {
            string result = hTTPResponse.Content.ReadAsStringAsync().Result;        
            response = [Code here...]
            //Codes here...
        }

        responses.Add(response);
    }

    return responses;
}