C#-为什么HttpClient PostAsync在.exe中块,但可以与Visual Studio 2015一起使用->;调试?
我有一个C#控制台应用程序,它必须创建一个HttpClient,并向我们的“3CX电话系统管理”门户网站提出一些请求(我必须检索/更改我们员工的电话状态)。为此,我必须登录,将收到的cookie保存到CookieContainer中,然后继续处理必须使用相同cookie的其他请求。代码如下:C#-为什么HttpClient PostAsync在.exe中块,但可以与Visual Studio 2015一起使用->;调试?,c#,post,cookies,visual-studio-2015,httpclient,C#,Post,Cookies,Visual Studio 2015,Httpclient,我有一个C#控制台应用程序,它必须创建一个HttpClient,并向我们的“3CX电话系统管理”门户网站提出一些请求(我必须检索/更改我们员工的电话状态)。为此,我必须登录,将收到的cookie保存到CookieContainer中,然后继续处理必须使用相同cookie的其他请求。代码如下: public static CookieContainer cookies = null; public static HttpClientHandler handler = new HttpClientH
public static CookieContainer cookies = null;
public static HttpClientHandler handler = new HttpClientHandler();
static void Main(string[] args) {
Task.Run(() => ExtListAsync());
Console.ReadLine();
}
static async Task<bool> LoginAsync() {
try {
cookies = new CookieContainer();
handler = new HttpClientHandler();
handler.CookieContainer = cookies;
using (HttpClient client = new HttpClient(handler, disposeHandler: false)) {
client.BaseAddress = new Uri("https://my.uri.com:5001");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
StringContent parameters = new StringContent(@"{""key"":""value"",""key2"":""value2""}", Encoding.UTF8, "application/json");
// BLOCKS HERE....
using (HttpResponseMessage response = await client.PostAsync("/api/other", parameters).ConfigureAwait(false)) {
using (HttpContent content = response.Content) {
string responseContent = content.ReadAsStringAsync().Result;
var responseCookies = cookies.GetCookies(uri).Cast<Cookie>();
if (responseCookies.Count() > 0)
{
return true;
}
else
{
return false;
}
}
}
}
} catch (HttpRequestException ex) {
Console.WriteLine("\n\r EXCEPTION MESSAGE: " + ex.Message);
Console.WriteLine("\n\r DATA: " + ex.Data);
Console.WriteLine("\n\r InnerException: " + ex.InnerException);
Console.WriteLine("\n\r Source: " + ex.Source);
Console.WriteLine("\n\r StackTrace: " + ex.StackTrace);
Console.WriteLine("\n\r TargetSite: " + ex.TargetSite);
return true;
}
}
static async Task ExtListAsync() {
bool loggedIn = await LoginAsync();
if (loggedIn) { ... }
}
发生了同样的事情:通过调试,它可以完美地工作:
状态代码200,原因短语:“确定”,响应内容:AuthSuccess
并且通过提示符.exe将不会协作。。但是如果我将3CX门户URL更改为另一个简单的网站,它检索一个静态网页(没有SSL),那么.exe就可以完美地工作 最后,我用Java编写了这个程序,它可以在控制台上完美地运行
try {
TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
};
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, acceptingTrustStrategy);
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build());
HttpClientContext context = HttpClientContext.create();
CookieStore cookieStore = new BasicCookieStore();
context.setCookieStore(cookieStore);
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(RequestConfig.custom()
.setCookieSpec(CookieSpecs.STANDARD).build()).setDefaultCookieStore(cookieStore).build();
HttpPost request = new HttpPost(mainUrl + loginUrl);
StringEntity params = new StringEntity("myJson");
request.addHeader("content-type", "application/json");
request.setEntity(params);
HttpResponse response = httpClient.execute(request, context);
System.out.println("Response getStatusLine: " +
response.getStatusLine());
} catch (...) { ... }
以及输出:
Response getStatusLine: HTTP/1.1 200 OK
最后,我用Java编写了这个程序,它可以在控制台上完美地运行
try {
TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
};
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, acceptingTrustStrategy);
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build());
HttpClientContext context = HttpClientContext.create();
CookieStore cookieStore = new BasicCookieStore();
context.setCookieStore(cookieStore);
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(RequestConfig.custom()
.setCookieSpec(CookieSpecs.STANDARD).build()).setDefaultCookieStore(cookieStore).build();
HttpPost request = new HttpPost(mainUrl + loginUrl);
StringEntity params = new StringEntity("myJson");
request.addHeader("content-type", "application/json");
request.setEntity(params);
HttpResponse response = httpClient.execute(request, context);
System.out.println("Response getStatusLine: " +
response.getStatusLine());
} catch (...) { ... }
以及输出:
Response getStatusLine: HTTP/1.1 200 OK
您是否设置了任何必需的请求头?服务器上有SSL转发吗?实际上没有,但是如果我尝试用Postman复制相同的POST/GET请求,它在没有任何SSL头或证书的情况下工作得很好。我用Chrome网络检测器嗅到了这些请求。你在Fiddler中看到了什么?很奇怪,它在debug/Postman中工作,但在通过exe运行时却不能工作。出于好奇,你到底是在为释放而建造吗?我还没试过用小提琴。。但我尝试在调试/发行版中为x64/任何CPU的任何组合构建它。。它工作的前2-3次,然后抛出HttpRequestException。服务器是我们的“3CX电话系统管理”门户,我必须检索我们的员工状态。@Jakasha这是因为您在async/await中混合了阻塞呼叫(
.Result
),这可能导致死锁。代码需要始终是异步的。您是否设置了任何必需的请求头?服务器上有SSL转发吗?实际上没有,但是如果我尝试用Postman复制相同的POST/GET请求,它在没有任何SSL头或证书的情况下工作得很好。我用Chrome网络检测器嗅到了这些请求。你在Fiddler中看到了什么?很奇怪,它在debug/Postman中工作,但在通过exe运行时却不能工作。出于好奇,你到底是在为释放而建造吗?我还没试过用小提琴。。但我尝试在调试/发行版中为x64/任何CPU的任何组合构建它。。它工作的前2-3次,然后抛出HttpRequestException。服务器是我们的“3CX电话系统管理”门户,我必须检索我们的员工状态。@Jakasha这是因为您在async/await中混合了阻塞呼叫(.Result
),这可能导致死锁。代码需要始终是异步的。