【问题标题】:HTTP Request works in Postman, but not in C# codeHTTP 请求在 Postman 中有效,但在 C# 代码中无效
【发布时间】:2019-11-11 09:25:24
【问题描述】:

我想在 C# 中执行一个简单的 HTTP 请求,但有些东西不起作用,我得到的只是403 Forbidden 状态码。

当我尝试在 Postman 中执行相同的请求时,一切正常。 我尝试运行 Fiddler 并查看 Postman 发送的所有标头。我复制粘贴了所有这些,但我仍然在 C# 代码发送的请求中得到403 Forbidden

C#代码(使用https://flurl.dev):

public static void Main(string[] args)
{
    FlurlHttp.Configure(settings => {
        settings.HttpClientFactory = new MyClientFactory();
    });

    var url = "https://example.com"
        .AppendPathSegments(new[] { "v1", "oauth", "accesstoken" })
        .SetQueryParam("grant_type", "client_credentials")
        .AllowAnyHttpStatus()
        .WithBasicAuth("username", "password")
        .WithHeaders(new {
            User_Agent = "Something/0.4.0 Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-G975F Build/NRD90M)",
            X_Secret_Header = "secret_encoded_value",
            accept_encoding = "gzip, deflate",
            Accept = "*/*"
        });

    HttpResponseMessage msg = url.GetAsync().Result;

    Console.WriteLine("StatusCodeString: " + msg.StatusCode.ToString());
    Console.WriteLine();
    Console.WriteLine(msg.Content.ReadAsStringAsync().Result);
}

class MyClientFactory : DefaultHttpClientFactory
{
    public override HttpMessageHandler CreateMessageHandler()
    {
        return new HttpClientHandler
        {
            AllowAutoRedirect = false
        };
    }
}

C# 请求和响应:

邮递员请求和响应:

有人能解释一下为什么这不起作用吗?相同的标题,相同的一切。

我将 URL 替换为“example.com”,因为我不想在此处显示真实的 API URL。

对于这么多图片也很抱歉。我不知道如何在此处以其他方式显示问题。

【问题讨论】:

  • 不要发布文字图片。
  • 你试过用C#的HttpClient吗?它会产生相同的结果吗?
  • 403 是否有可能来自代理服务器?
  • @TobiasTengler 是的,我尝试使用 HttpClient 并产生相同的结果。
  • @JohnWu 当我使用 Fiddler 运行请求时,Postman 和 C# 都返回 403。但是没有 Fiddler,Postman 可以工作,但 C# 不能

标签: c# http request postman flurl


【解决方案1】:

在 Postman 的右侧应该有一个名为 code 的链接。单击它,然后选择 C# 以获取 Postman 生成的代码。将其粘贴并尝试一下。

【讨论】:

    【解决方案2】:

    我知道这很老,但要获得与邮递员发送的相同 C# 代码,让邮递员生成代码,但首先您必须从 nuget 或 PM 控制台获取 RestSharp 库,输入:

    Install-Package RestRequest -Version 1.2.0

    步骤:

    1- 从邮递员那里调用你的 rest api

    2- 按密码按钮 3-将打开一个弹出窗口,然后选择您想要的任何语言,在您的情况下是 C#

    【讨论】:

      【解决方案3】:

      对我来说,问题在于 C# 中的 TLS 设置。尝试在应用的开头或 HTTP 请求代码之前添加这一行:

      ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
      

      【讨论】:

      • 天哪,这对我有用,谢谢!!但是为什么将其更改为此特定协议有效?
      【解决方案4】:

      我的建议是从邮递员和 C# 应用程序中检索原始请求字符串,并使用 https://text-compare.com/ 之类的东西来查找差异。猜测是有一些非常小的差异,比如额外的斜线,用普通的眼睛很难注意到。

      【讨论】:

      • 我使用您提供的站点比较了请求字符串,但结果显示:“两个文本相同”
      【解决方案5】:

      下一步是比较来自您的 C# 代码和 Postman 的原始请求和响应,将它们并排放置并比较差异 - 我向您保证至少会有一个。 :-)

      403authorization problem,因此令牌将是第一个嫌疑人,因为您的请求结构错误更有可能引发 400“错误请求”错误。

      不过,在这种特殊情况下,我已经使用 Flurl 在我的机器上运行了 VS2019 中的代码,它似乎运行良好。 它返回一个示例 HTML 页面:

      <!doctype html>
      <html>
      <head>
          <title>Example Domain</title>
      
          <meta charset="utf-8" />
          <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
          <meta name="viewport" content="width=device-width, initial-scale=1" />
          <style type="text/css">
          body {
              background-color: #f0f0f2;
              margin: 0;
              padding: 0;
              font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
      
          }
          div {
              width: 600px;
              margin: 5em auto;
              padding: 50px;
              background-color: #fff;
              border-radius: 1em;
          }
          a:link, a:visited {
              color: #38488f;
              text-decoration: none;
          }
          @media (max-width: 700px) {
              body {
                  background-color: #fff;
              }
              div {
                  width: auto;
                  margin: 0 auto;
                  border-radius: 0;
                  padding: 1em;
              }
          }
          </style>
      </head>
      
      <body>
      <div>
          <h1>Example Domain</h1>
          <p>This domain is established to be used for illustrative examples in documents. You may use this
          domain in examples without prior coordination or asking for permission.</p>
          <p><a href="http://www.iana.org/domains/example">More information...</a></p>
      </div>
      </body>
      </html>
      

      【讨论】:

      • 我用“example.com”替换了实际的url,因为我不想在这里显示真正的api
      • 好的,你的代码可以工作了。现在从工作示例转到邮递员“授权”选项卡,检查您使用的令牌是否与您在 VS 代码中的令牌相同
      【解决方案6】:

      以防万一这对任何人都有帮助。我在调用的 api 上遇到了同样的问题,并且有点不知所措,因为邮递员和 Visual Studio 之间的所有内容(包括授权标头)似乎完全相同。但是当我真正仔细查看提琴手时,我注意到在使用邮递员时,被调用的 api 是 https://api.someplace.com/properties/?pagesize=20 而在视觉工作室中我有 https://api.someplace.com/properties?pagesize=20

      请注意“属性”和查询字符串之间缺少斜线。 “...properties/?...” 工作正常,“...properties?...” 导致 403。

      我认为(如果我在这里错了,显然纠正我)实际发生的情况是,在第一个 http 调用中,缺少斜杠,服务器使用斜杠将 HTTP 301 重定向到 api。当重定向发生时,授权标头没有被携带,这导致了 403 授权错误。

      现在我不知道为什么需要此重定向,我构建的任何 api 都允许这两种情况,并且不需要重定向。但最后,我只是将 url 更改为“../properties/?etc...”,问题就消失了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-11-28
        • 2018-07-24
        • 1970-01-01
        • 2018-07-14
        • 1970-01-01
        • 2017-05-03
        • 2022-10-31
        • 2017-09-14
        相关资源
        最近更新 更多