【问题标题】:C# - How to I get the HTTP Status Code from a http requestC# - 如何从 http 请求中获取 HTTP 状态代码
【发布时间】:2019-12-11 10:57:25
【问题描述】:

我有以下代码,作为 POST 请求按预期工作(给定正确的 URL 等)。似乎我在阅读状态码时遇到了问题(我收到了成功的 201,并且基于该数字我需要继续处理)。知道如何获取状态码吗?

static async Task CreateConsentAsync(Uri HTTPaddress, ConsentHeaders cconsentHeaders, ConsentBody cconsent)
{
    HttpClient client = new HttpClient();

    try
    {
        client.BaseAddress = HTTPaddress;
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
        client.DefaultRequestHeaders.Add("Connection", "keep-alive");
        client.DefaultRequestHeaders.Add("Cache-Control", "no-cache");

        client.DefaultRequestHeaders.Add("otherHeader", myValue);
        //etc. more headers added, as needed...

        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, client.BaseAddress);

        request.Content = new StringContent(JsonConvert.SerializeObject(cconsent, Formatting.Indented), System.Text.Encoding.UTF8, "application/json");

        Console.WriteLine("\r\n" + "POST Request:\r\n" + client.DefaultRequestHeaders + "\r\nBody:\r\n" + JsonConvert.SerializeObject(cconsent, Formatting.Indented) + "\r\n");

        await client.SendAsync(request).ContinueWith
        (
            responseTask => 
            {
                Console.WriteLine("Response: {0}", responseTask.Result + "\r\nBody:\r\n" + responseTask.Result.Content.ReadAsStringAsync().Result);
            }
        );

        Console.ReadLine();
    }
    catch (Exception e)
    {
        Console.WriteLine("Error in " + e.TargetSite + "\r\n" + e.Message);
        Console.ReadLine();
    }
}

【问题讨论】:

  • 你已经在async函数中,所以你不需要使用ContinueWith

标签: c# api httprequest


【解决方案1】:

您的结果中有一个状态代码。

responseTask.Result.StatusCode

甚至更好

    var response = await client.SendAsync(request);
    var statusCode = response.StatusCode;

【讨论】:

  • 如果成功,上述内容会不会简单地返回响应OK? OP不也是要代码的吗?
  • 这将返回状态码。 Ok 是 200,如果是别的,就是那个值。
  • 是的,要返回你需要做的状态码值(int)response.StatusCode
  • 状态码有多个枚举。 docs.microsoft.com/en-us/dotnet/api/…你可以对比一下。
  • continue with 返回一个Task 而不是响应值,因此需要将var 更改为HttpResponseMessage response = await ...。我建议您删除 continueWith,因为它根本不需要,并继续使用我在上面与您共享的代码(没有 continueWith)。
【解决方案2】:
  • 如果您已经在 async 函数中,则避免使用 ContinueWith 会有所帮助,因为您可以使用(更简洁的)await 关键字。

  • 如果您通过await 调用SendAsync,您将获得一个HttpResponseMessage 对象,您可以从以下位置获得状态码:

  • 另外,将 IDisposable 对象包装在 using() 块中(HttpClient 除外 - 它应该是 static 单例或更好,请使用 IHttpClientFactory)。

  • 不要将HttpClient.DefaultRequestHeaders 用于特定于请求的标头,而应使用HttpRequestMessage.Headers

  • Connection: Keep-alive 标头将由HttpClientHandler 自动为您发送。
  • 您确定需要在请求中发送Cache-control: no-cache 吗?如果您使用的是 HTTPS,那么几乎可以保证不会有任何代理缓存导致任何问题 - 而且HttpClient 也不使用 Windows Internet 缓存。
  • 不要使用Encoding.UTF8,因为它会添加一个前导字节顺序标记。请改用私有 UTF8Encoding 实例。
  • Always use .ConfigureAwait(false) 与每个 await 一起用于不在线程敏感上下文(例如 WinForms 和 WPF)中运行的代码。
private static readonly HttpClient _httpClient = new HttpClient();
private static readonly UTF8Encoding _utf8 = new UTF8Encoding( encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true );

static async Task CreateConsentAsync( Uri uri, ConsentHeaders cconsentHeaders, ConsentBody cconsent )
{
    using( HttpRequestMessage req = new HttpRequestMessage( HttpMethod.Post, uri ) )
    {
        req.Headers.Accept.Add( new MediaTypeWithQualityHeaderValue("*/*") );
        req.Headers.Add("Cache-Control", "no-cache");
        req.Headers.Add("otherHeader", myValue);
        //etc. more headers added, as needed...

        String jsonObject = JsonConvert.SerializeObject( cconsent, Formatting.Indented );
        request.Content = new StringContent( jsonObject, _utf8, "application/json");

        using( HttpResponseMessage response = await _httpClient.SendAsync( request ).ConfigureAwait(false) )
        {
            Int32 responseHttpStatusCode = (Int32)response.StatusCode;
            Console.WriteLine( "Got response: HTTP status: {0} ({1})", response.StatusCode, responseHttpStatusCode );
        }
    }
}

【讨论】:

  • 非常感谢您的回复(双关语不是有意的:-) - 我如何“获取 HttpResponseMessage 对象”并读取数字(即 200 或 201 等) - 请您发布一个片段?同样重要的是:如何避免上述代码中的 ContinueWith?提前谢谢你!
  • 非常感谢,事实上对我的代码进行了很好的升级。但是,ConsoleWriteLine("Got response... 返回一个字符串(在我的情况下,"Created" 当然取决于其余的 API - 但不是 HTTP 代码,我期待的是 int,即 200、201 等)
  • @Nick 要获得Int32/int 状态码,请转换StatusCode 属性。我已经更新了我的答案。
【解决方案3】:

您可以简单地检查响应的 StatusCode 属性:

https://docs.microsoft.com/en-us/previous-versions/visualstudio/hh159080(v=vs.118)?redirectedfrom=MSDN

static async void dotest(string url)
{
    using (HttpClient client = new HttpClient())
    {
        HttpResponseMessage response = await client.GetAsync(url);

        if (response.IsSuccessStatusCode)
        {
            Console.WriteLine(response.StatusCode.ToString());
        }
        else
        {
            // problems handling here
            Console.WriteLine(
                "Error occurred, the status code is: {0}", 
                response.StatusCode
            );
        }
    }
}

【讨论】:

  • response 对象应包装在 using 块中。此外,HttpClient 对象不应该是短命的(所以不要立即处置 HttpClient)。
【解决方案4】:

@AthanasiosKataras 对于返回状态码本身是正确的,但如果您还想返回状态码值(即 200、404)。您可以执行以下操作:

var response = await client.SendAsync(request);
int statusCode = (int)response.StatusCode

以上将为您提供 int 200。

编辑:

你没有理由不能做以下事情吗?

using (HttpResponseMessage response = await client.SendAsync(request))
{
    // code
    int code = (int)response.StatusCode;
}

【讨论】:

  • 这似乎太接近了!我可以如何修改我的陈述? await client.SendAsync(request).ContinueWith(responseTask => { Console.WriteLine("RESPONSE: {0}", responseTask.Result.StatusCode); });当我使用它时,我得到一个字符串,即“Created”等,但是当我使用 responseTask.Result.StatusCode.GetTypeCode();我收到 Int32 !这个 200 或 201 号码在哪里......?
  • @Nick (int)responseTask.Result.StatusCode
  • 根据之前的评论:非常有用的提示。我做 var response await client.SendAsync(request).ContinueWith(responseTask => {Console.WriteLine("RESPONSE: {0}", responseTask.Result.... 然后 "int statusCode = (int)response.StatusCode; " 但我在第一条语句(var 响应等待...)中收到一条错误消息:必须初始化隐式类型变量。请问我错过了什么?...
  • @Nick 如果你在response 上停止它,它有价值吗?
  • 你的意思是在 var response = await client... etc.. ?不幸的是,它在那里抛出错误,我非常想调试它。说“必须初始化隐式类型的变量”,但我不知道初始化它的内容..
猜你喜欢
  • 2014-07-17
  • 1970-01-01
  • 2019-07-22
  • 2012-03-09
  • 1970-01-01
  • 1970-01-01
  • 2021-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多