C#-为什么HttpClient PostAsync在.exe中块,但可以与Visual Studio 2015一起使用->;调试?

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

我有一个C#控制台应用程序,它必须创建一个HttpClient,并向我们的“3CX电话系统管理”门户网站提出一些请求(我必须检索/更改我们员工的电话状态)。为此,我必须登录,将收到的cookie保存到CookieContainer中,然后继续处理必须使用相同cookie的其他请求。代码如下:

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
),这可能导致死锁。代码需要始终是异步的。