json C# HTTPClient响应日志

kcwpcxri  于 2023-10-21  发布在  C#
关注(0)|答案(2)|浏览(172)

我有下面的代码,我用它来发送JSON数据到一个使用HTTPClient的API。我想记录HTTP响应/状态代码,如200,201,400等。请问有人可以帮助我如何记录响应代码?

Current code:

      public void Main()
        {
            //String filePath = @"your-path\test.json";
            String filepath = Dts.Variables["User::FileName"].Value.ToString();
            if (File.Exists(filepath))
            {
                try
                {
                    // Read the JSON file
                    string jsonData = File.ReadAllText(filepath);
                    using (var client = new HttpClient())
                    {
                        client.BaseAddress = new Uri("https://your-url.com");
                        var response = client.PostAsync("/url-path", new StringContent(jsonData, Encoding.UTF8, "application/json")).Result;
                        var responseContent = response.Content.ReadAsStringAsync();

                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error reading or parsing the JSON file: {ex.Message}");
                }
            }
            else
            {
                Console.WriteLine("The JSON file does not exist in the specified folder.");
            }
        }
    }
ocebsuys

ocebsuys1#

PostAsync方法返回一个HttpResponseMessage,它包含Islam StatusCode和StatusCode属性。如果你使用它们,你的代码将是这样的:

public void Main()
{
    //String filePath = @"your-path\test.json";
    String filepath = Dts.Variables["User::FileName"].Value.ToString();
    if (File.Exists(filepath))
    {
        try
        {
            // Read the JSON file
            string jsonData = File.ReadAllText(filepath);
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri("https://your-url.com");
                var response = client.PostAsync("/url-path", new StringContent(jsonData, Encoding.UTF8, "application/json")).Result;
                if (response.IsSuccessStatusCode)
                {
                    Console.WriteLine(response.StatusCode.ToString());

                    var responseContent = response.Content.ReadAsStringAsync();
                }

            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error reading or parsing the JSON file: {ex.Message}");
        }
    }
    else
    {
        Console.WriteLine("The JSON file does not exist in the specified folder.");
    }
}
}
iyr7buue

iyr7buue2#

HttpClient.PostAsync方法返回HttpResponseMessage对象,其中包含StatusCode属性和其他有关响应的附加信息。
因此,您可以在执行后通过使用以下字符串示例将其作为“StatusCode(StatusCodeDescription)”获取:$"{(int)response.StatusCode} ({response.ReasonPhrase})"(输出如200 (OK)500 (InternalServerError)等):

public void Main()
{
    // ...
    using (var client = new HttpClient())
    {
        // ...
        var response = client.PostAsync(...).Result;
        // ...
        Console.WriteLine($"{(int)response.StatusCode} ({response.ReasonPhrase})"); 
        // ...
    }
}

但是,请求的执行也可能抛出HttpRequestException(最简单的例子是超时)。而且,如果你在try-block中声明了HttpClientHttpResponseMessage,你就不能在catch-block中得到response信息。这就是为什么你应该在try-catch块中声明它:

public void Main()
{
    // ...
    var client = new HttpClient();
    var response = (HttpResponseMessage?)null;
    // ...
    try
    {
        // ...
        response = client.PostAsync(...).Result;
        // ...
        Console.WriteLine($"{(int)response.StatusCode} ({response.ReasonPhrase})");
    }
    catch (Exception ex)
    {
        // Here you have access to response object, but don't forget null-checks
        Console.WriteLine($"{(int?)response?.StatusCode} ({response?.ReasonPhrase})");
    }
}

此外,应该提到很多关于代码的东西,比如:

  • 不要在方法内部声明HttpClient以避免开销(参见this question);
  • 不要在可等待的Task上使用.Result,以避免死锁(请参阅this question);
  • 别忘了把你的Task给我。代码responseContent = response.Content.ReadAsStringAsync()中的一行代码将Task<string>对象存储在responseContent变量中,而不是像您期望的那样纯string。你应该await这个调用来获取字符串。

假设是这样,我建议您只声明和初始化HttpClient一次,在方法之外的某个地方,然后重用它。另外,将方法标记为async,以便能够等待HttpClient调用。通过这种方式,您可以获得正确的请求调用,响应处理和记录响应的能力。简单的例子:

private static readonly HttpClient _client = new() { BaseAddress = new Uri("SomeBaseUri") };

public static async Task Main()
{
    // ...
    var response = (HttpResponseMessage?)null;
    var responseContent = string.Empty;
    // ...
    try
    {
        // ...
        response = await _client.PostAsync(...);
        responseContent = await response.Content.ReadAsStringAsync();
        // ...
        Console.WriteLine($"Request executed with status: {(int)response.StatusCode} ({response.ReasonPhrase}). " +
                          $"Response body: {responseContent}");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Request failed with status: {(int?)response?.StatusCode} ({response?.ReasonPhrase}). " + 
                          $"Error: {ex.Message}");
    }

    // If job with HttpClient done - don't forget to dispose it manually:
    _client.Dispose();
}

相关问题