2017-09-14 10 views
1

私はHttpClientを作成し、私たちの "3CX電話システム管理" Webポータル(従業員の電話ステータスを取得/変更する必要があります)に何らかの要求をしなければならないC#コンソールアプリケーションを持っています。これを行うには、ログインして、受信したCookieをCookieContainerに保存してから、同じCookieを使用する必要がある他のリクエストを続行する必要があります。ここにコード:C# - なぜHttpClient PostAsyncは.exeでブロックされますが、Visual Studio 2015で動作しますか - >デバッグ?

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) { ... } 
} 

Visual Studio "Start Debugging"で起動したこの単純なコードは正しく実行されます。 私のコマンドプロンプトから.exeを起動しようとすると(Adminモードでも試されます)、アプリケーションが少し遅れて正しく実行されることがありますが、ほとんどの場合、 "await client.PostAsync(...

EXCEPTION MESSAGE: An error occurred while sending the request. 

DATA: System.Collections.ListDictionaryInternal 

InnerException: System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond xxx.xxx.xxx.xxx:5001 
    at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult) 
    at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception) 
    --- End of inner exception stack trace --- 
    at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context) 
    at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar) 

Source: mscorlib 

StackTrace: at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 
    at statusmng3cx.Program.<LoginAsync>d__15.MoveNext() in ...\myPath\Program.cs:line 254 

TargetSite: Void Throw() 

誰かがそのための説明があります。)」...し、その後HttpRequestExceptionをtrows? ありがとうございます。

UPDATE:

私もSSL証明書を追加しようとしました:

WebRequestHandler whandler = new WebRequestHandler(); 
whandler.ClientCertificateOptions = ClientCertificateOption.Manual; 

var pem = System.IO.File.ReadAllText("mycert.pem"); 
byte[] certBuffer = GetBytesFromPEM(pem, "CERTIFICATE"); 
X509Certificate2 certificate = new X509Certificate2(certBuffer); 

whandler.ClientCertificates.Add(certificate); 

using (var httpClient = new HttpClient(whandler)) { ... as above ... } 

そして、同じことが起こる:デバッグを経由して、それは完璧に動作します: ステータスコード200を、のreasonPhrase ' OK、responseContent:AuthSuccess、...

プロンプトを介して.exeは協力しません。しかし、3CX PortalのURLを静的なWebページ(wi SSLより)、.exeは完全に動作します。

+0

はあなたが必要なリクエストヘッダを設定していますか?サーバー上にSSLが転送されていますか? – DiskJunky

+0

実際にはありませんが、Postmanで同じPOST/GETリクエストを複製しようとすると、SSLヘッダーや証明書がなくてもうまく動作します。私はChromeネットワークのインスペクタでこれらのリクエストを盗聴しました。 – Jakasha

+0

フィドラーには何が見えますか?間違いなく、それはデバッグ/ Postmanでは動作しますが、exeで動作する場合は動作しません。不思議なことから、あなたはリリースのために何かを構築していますか? – DiskJunky

答えて

0

最後に私は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 
関連する問題