https获取请求在邮递员和浏览器中传递但在代码中失败

时间:2019-07-25 12:59:10

标签: c#

我正在尝试在.net 4.5上使用c#通过rest API获取json 我已经在代码中尝试了各种方法,但最终所有结果都让我得到了

  

“身份验证失败,因为远程方已关闭   transportstream”。

完全相同的URL可通过浏览器和邮递员使用。

到目前为止,我尝试使用.net的webClient,httpClient和httpWebRequest获得相同的结果。我已经尝试过比较邮递员和我的代码之间的请求(通过requestBin),但是即使它们是相同的,我仍然会不断返回
 “验证失败,因为远程方已关闭传输”。 我当前的代码正在使用httpWebRequest,但是每种解决方案都可以。

我已经使用了所有安全协议,其中一些会导致api返回404,有些会导致服务器返回

  

“身份验证失败,因为远程方已关闭   运输流”。

这是我当前的代码:

 public string GetCityStreets()
        {

                var url = "https://data.gov.il/api/action/datastore_search?resource_id=a7296d1a-f8c9-4b70-96c2-6ebb4352f8e3&q=26";
                var request = (HttpWebRequest)WebRequest.Create(url);
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 |
                                                       SecurityProtocolType.Tls12 |
                                                       SecurityProtocolType.Tls11 |
                                                       SecurityProtocolType.Tls;

                var response = (HttpWebResponse)request.GetResponse();

                string jsonResponse;

                using (var reader = new StreamReader(response.GetResponseStream()))
                {
                     jsonResponse = reader.ReadToEnd();
                }

                return jsonResponse;
        }

在我当前的代码中,当实际发出请求时会抛出异常[request.GetResponse()]。从本质上讲,我需要从api中获取json。

感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

服务器端似乎正在检查用户代理(大概是为了阻止漫游器和其他代码(如您的!)击中端点)。要绕过此操作,您需要将用户代理设置为一个值,使其认为您是Web浏览器。

request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36";
例如,

有效。

您可能希望考虑(在应用启动时)一次设置ServicePointManager.SecurityProtocol (而不是在每次请求时)。

答案 1 :(得分:1)

设置SecurityProtocolType.Tls12 之前,以初始化请求:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12` 
var request = WebRequest.CreateHttp(url);

如果您使用的是Windows7。在Windows 10上,您只需要SecurityProtocolType.SystemDefault


注意:要启用 TLS1.3 (在Windows 7和Windows 10中均可用),如果不使用.Net 4.8.Net Core 3.0,因为没有它的枚举器,所以可以使用以下命令进行设置:

var secProtoTls13 = (SecurityProtocolType)12288;

删除在此设置的所有其他SecurityProtocolType

也必须设置User-Agent标头,否则您将收到404(未找到)。这是FireFox标头:

request.UserAgent = "Mozilla/5.0 (Windows NT 10; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0";

用户代理标头上的注释:该特定站点不会激活HTTP Strict Transport Security(HSTS)。但是某些站点会在看到表示WebBrowser支持该站点。 HttpWebRequest不理解它,因此它只是等待一个永远不会出现的响应,因为站点正在等待交互
您可能要改用IE11标头。

还添加另一个标题:

 request.Headers.Add(HttpRequestHeader.CacheControl, "no-cache");

答案 2 :(得分:0)

这可用于HttpClient(.net 4.5及更高版本)

    var url = "https://data.gov.il/api/action/datastore_search?resource_id=a7296d1a-f8c9-4b70-96c2-6ebb4352f8e3&q=26";
    var client = new HttpClient();
    client.DefaultRequestHeaders.Add("User-Agent", "C# App");
    Task<string> response =  client.GetStringAsync(url);
    Console.WriteLine(response.Result); 

认为服务器需要用户代理。

相关问题