使用 C# HttpClient API 和 postman 测试的区别?客户端调用适用于邮递员,但不适用于 C# httpClient getAsync

Posted

技术标签:

【中文标题】使用 C# HttpClient API 和 postman 测试的区别?客户端调用适用于邮递员,但不适用于 C# httpClient getAsync【英文标题】:Differences between using C# HttpClient API and the postman testing? Client call works on postman, but not C# httpClient getAsync 【发布时间】:2016-12-13 19:37:44 【问题描述】:

我正在测试一个 REST API 帖子,当我在 Postman 上试用它时效果很好。但是,在某些情况下(与发布 XML 数据相关),如果我使用 HttpClient API 发布,我会收到以下错误:

无法从传输连接读取数据:现有连接被远程主机强行关闭。

但相同的 XML 内容在 Postman 上运行良好,状态正常且响应正确。

使用 C# HttpClient API 和 postman 测试有什么区别?如何配置我的 API 调用以匹配邮递员的行为?

这里附上源代码,和邮递员截图

public void createLoan()

    string baseCreateLoanUrl = @"https://serverhost/create?key=";
    var strUCDExport = XDocument.Load(@"C:\CreateLoan_testcase.xml");

    using (var client = new HttpClient())
    
        var content = new StringContent(strUCDExport.ToString(), Encoding.UTF8, Mediatype);
        string createLoanApi = string.Concat(baseCreateLoanUrl, APIKey);

        try
        
            var response = client.PostAsync(createLoanApi, content).Result;
        
        catch (Exception ex)
        
            MessageBox.Show("Error Happened here...");
            throw;
        

        if (response.IsSuccessStatusCode)
        
            // Access variables from the returned JSON object
            string responseString = response.Content.ReadAsStringAsync().Result;
            JObject jObj = JObject.Parse(responseString);

            if (jObj.SelectToken("failure") == null)
            
                // First get the authToken
                string LoanID = jObj["loanStatus"]["id"].ToString();
                MessageBox.Show("Loan ID: " + LoanID);
            
            else
            
                string getTokenErrorMsg = string.Empty;

                JArray errorOjbs = (JArray) jObj["failure"]["errors"];
                foreach (var errorObj in errorOjbs)
                
                    getTokenErrorMsg += errorObj["message"].ToString() + Environment.NewLine;
                
                getTokenErrorMsg.Dump();
            
        
    

【问题讨论】:

你可以在你的帖子上添加你的合同(界面)吗? 对不起@ahankendi,很遗憾,我无法访问服务器端 api。 虽然它可能与您的问题没有太大关系,但请停止使用 .Result 并开始使用 await 。 .Result 会阻塞你的线程,如果你不小心可能会导致死锁。我建议学习如何使用 async/await,这将使您的生活变得更加轻松。 :) 感谢您的评论,克里姆。我实际上尝试了所有方法,包括 async/await 甚至像 Nard 之前在下面建议的单例,但它们都返回相同的错误。 如果其他人偶然发现这个问题,解决我的问题是设置允许的安全协议:System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 |安全协议类型.Tls12;礼貌:***.com/a/46223433/1243268 【参考方案1】:

感谢 Nard 的评论,比较标头后,我发现我的客户端标头存在以下问题: 期望:100-继续

而邮递员没有。

一旦我使用 ServicePointManager 删除它:

ServicePointManager.Expect100Continue = false;

现在一切似乎都很好。谢谢大家的意见!

【讨论】:

【参考方案2】:

我的直觉告诉我这很简单。首先,我们知道 API 有效,所以我认为这取决于您如何使用 HttpClient。

首先,按照this SO answer 的建议尝试,将其创建为单例并完全放弃 using 语句,因为共识是不需要释放 HttpClient:

    private static readonly HttpClient HttpClient = new HttpClient();

我认为它可能存在或您的内容编码行有问题导致 API 出现问题。有没有你不喜欢的东西,我敢打赌 Postman 和这里的请求有所不同。也许尝试将其作为 JSON ala 发送:

     var json = JsonConvert.SerializeObject(strUCDExport.ToString());
     var content = new StringContent(json, Encoding.UTF8, Mediatype);

也许 Postman vs yours 的标题会显示一些缺失的东西,我认为真正的答案会在那里。让 fiddler 在后台运行,通过 Postman 发送,检查,然后运行代码并重新检查。密切注意 Postman 标头上的所有属性标签,API 有效,因此缺少某些内容。 Fiddler 会告诉你的。

【讨论】:

感谢 Nard 的详细建议。然而,现在当我让提琴手跑到一边时。我没有像以前那样出现错误,而是得到了“贷款号码已经存在的贷款:“1612EM000064”,这听起来像api有两个镜头,我得到了第二个响应......为什么提琴手会导致这个? 使用提琴手逐行比较标题后解决,删除“期望:100-继续”完成了工作。详情请查看我自己的帖子。【参考方案3】:

当我偶然发现 Fiddler 时,我为此苦苦挣扎了 2 天,它可以让您记录服务的流量。在比较了调用后,我发现我的代码中错过了一个标题。

【讨论】:

以上是关于使用 C# HttpClient API 和 postman 测试的区别?客户端调用适用于邮递员,但不适用于 C# httpClient getAsync的主要内容,如果未能解决你的问题,请参考以下文章

C#中HttpClient使用注意:预热与长连接

如何使用httpclient c#调用bitly v4 api来缩短url?

如何在 C# 中使用 HttpClient 读取 Web api 响应

C#中HttpClient使用注意:预热与长连接

C# Xamarin 文件上传到 API 可以使用 RestSharp,但不能使用 HttpClient

用于 C# 应用程序的 HttpClient