2013-04-08 16 views
8

をPUT例外が発生します:C#のHttpClient何らかの理由で結果的に今働いていた私の以下のコードを

public static async Task<string> HttpPut(string inUrl, string inFilePath) 
    { 
     using (var handler = new HttpClientHandler 
     { 
      AllowAutoRedirect = false 
     }) 
     { 
      using (var client = new HttpClient(handler)) 
      { 
       //var content = new StreamContent(new FileStream(inFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, useAsync: true)); 
       using (var content = new StreamContent(new FileStream(inFilePath, FileMode.Open))) 
       { 
        content.Headers.Remove("Content-Type"); 
        content.Headers.Add("Content-Type", "application/octet-stream"); 

        using (var req = new HttpRequestMessage(HttpMethod.Put, inUrl)) 
        { 
         string authInfo = String.Format("{0}:{1}", Program.Config.MediaStorageList.Find(o => o.Name == "Viz Media Engine Test").UserName, Program.Config.MediaStorageList.Find(o => o.Name == "Viz Media Engine Test").Password); 
         authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo)); 
         req.Headers.Add("Authorization", "Basic " + authInfo); 
         req.Headers.Remove("Expect"); 
         req.Headers.Add("Expect", ""); 
         //req.Headers.TransferEncodingChunked = true; 

         req.Content = content; 

         // Ignore Certificate validation failures (aka untrusted certificate + certificate chains) 
         ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true); 

         using (HttpResponseMessage resp = await client.SendAsync(req)) 
         { 
          //This part is specific to the setup on an Expo we're at... 
          if (resp.StatusCode == HttpStatusCode.Redirect || resp.StatusCode == HttpStatusCode.TemporaryRedirect) 
          { 
           string redirectUrl = resp.Headers.Location.ToString(); 

           if (redirectUrl.Contains("vme-store")) 
           { 
            redirectUrl = redirectUrl.Replace("vme-store", "10.230.0.11"); 
           } 
           return await HttpPut(redirectUrl, inFilePath); 
          } 

          resp.EnsureSuccessStatusCode(); 

          return await resp.Content.ReadAsStringAsync(); 
         } 
        } 
       } 
      } 
     } 
    } 

私は取得しています例外がある:

System.NotSupportedException was unhandled 
HResult=-2146233067 
Message=The stream does not support concurrent IO read or write operations. 
Source=System 
StackTrace: 
    at System.Net.ConnectStream.InternalWrite(Boolean async, Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state) 
    at System.Net.ConnectStream.BeginWrite(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state) 
    at System.Net.Http.StreamToStreamCopy.BufferReadCallback(IAsyncResult ar) 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 
    at VizWolfInnerServer.Tools.HttpConnector.<HttpPut>d__39.MoveNext() in c:\Users\christer\Documents\Visual Studio 2012\Projects\VizWolfNew\VizWolfInnerServer\Tools\HttpConnector.cs:line 202 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 
    at VizWolfInnerServer.Tools.VizAPIConnector.<VmeUploadMedia>d__0.MoveNext() in c:\Users\christer\Documents\Visual Studio 2012\Projects\VizWolfNew\VizWolfInnerServer\Tools\VizAPIConnector.cs:line 187 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__1(Object state) 
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() 
    at System.Threading.ThreadPoolWorkQueue.Dispatch() 
InnerException: 

、私は非常に抱えていますHttpClientの適切なドキュメントとサンプルを見つけるのは苦労します。なぜこれが突然動作しないのか(ストリームコンテンツの代わりにStringContentと全く同じメソッドが完全に動作します)を理解するのに苦労しています...

もともとはそれ自身のスレッドから呼び出され、その後、次のように:

public static async void VmeUploadMedia(string inUploadLink, string inFilePath) 
{ 
    string result = await HttpConnector.HttpPut(inUploadLink, inFilePath); 
} 

誰もが明らかに何かを発見しますか?

おかげ

UPDATE

は、博覧会、みんながそれを自分のストレージ名をマップするために得ることが判明し、私は最善の解決策だった戻って私の元のコードに行くことができるようにIPです。私が持っていた問題はAllowAutoRedirect = falseと関係しています。実際にリダイレクトが行われていない場合でも、HttpResponseMessage resp = clientAttendTime(req)で例外が発生しました。私は種類のそれも起こっていた理由を失ったんだけど、このコードを使用すると、すべてが今取り組んでいる:

public static async Task<string> HttpPut(string inUrl, string inFilePath) 
    { 
     using (var client = new HttpClient()) 
     { 
      using (var content = new StreamContent(File.OpenRead(inFilePath))) 
      { 
       content.Headers.Remove("Content-Type"); 
       content.Headers.Add("Content-Type", "application/octet-stream"); 

       using (var req = new HttpRequestMessage(HttpMethod.Put, inUrl)) 
       { 
        string authInfo = String.Format("{0}:{1}", Program.Config.MediaStorageList.Find(o => o.Name == "Viz Media Engine Test").UserName, Program.Config.MediaStorageList.Find(o => o.Name == "Viz Media Engine Test").Password); 
        authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo)); 
        req.Headers.Add("Authorization", "Basic " + authInfo); 
        req.Headers.Remove("Expect"); 
        req.Headers.Add("Expect", ""); 

        req.Content = content; 

        // Ignore Certificate validation failures (aka untrusted certificate + certificate chains) 
        ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true); 

        using (HttpResponseMessage resp = await client.SendAsync(req)) 
        { 
         resp.EnsureSuccessStatusCode(); 

         return await resp.Content.ReadAsStringAsync(); 
        } 
       } 
      } 
     } 
    } 

あなたがHttpPut()を呼び出しているように見えます

+0

を手助けしようとしていた人々に

public static async Task<string> HttpPut(string inUrl, string inFilePath) { using (var client = new HttpClient()) { using (var content = new StreamContent(File.OpenRead(inFilePath))) { content.Headers.Remove("Content-Type"); content.Headers.Add("Content-Type", "application/octet-stream"); using (var req = new HttpRequestMessage(HttpMethod.Put, inUrl)) { string authInfo = String.Format("{0}:{1}", Program.Config.MediaStorageList.Find(o => o.Name == "Viz Media Engine Test").UserName, Program.Config.MediaStorageList.Find(o => o.Name == "Viz Media Engine Test").Password); authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo)); req.Headers.Add("Authorization", "Basic " + authInfo); req.Headers.Remove("Expect"); req.Headers.Add("Expect", ""); req.Content = content; // Ignore Certificate validation failures (aka untrusted certificate + certificate chains) ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true); using (HttpResponseMessage resp = await client.SendAsync(req)) { resp.EnsureSuccessStatusCode(); return await resp.Content.ReadAsStringAsync(); } } } } } 

感謝をサイト上の実際の回答と正しい答えとして選択します。現時点では未回答の質問のようです。 – dmportella

+0

良い点、今やって – CeeRo

+0

あなたは今、PutAsJsonAsync <>を使用していませんか? – niico

答えて

4

エクスポ・ガイが自分のストレージネームをIPにマッピングするようになったので、元のコードに戻って最高の解決策でした。私が持っていた問題はAllowAutoRedirect = falseと関係しています。実際にリダイレクトが行われていない場合でも、HttpResponseMessage resp = clientAttendTime(req)で例外が発生しました。私は種類のそれも起こったが、このコードのすべてのものを使用していた理由を迷ってしまいましたが、今働いている:あなたのように答える追加する大丈夫です

+0

thats :) all good – dmportella

0

を手助けしようとしていた人たちに感謝します再び、あなたはまだFileStreamを開いています。あなた自身の中から再帰的にHttpPut()を呼び出す前に、FileStreamを破棄してみてください。

//This part is specific to the setup on an Expo we're at... 
          if (resp.StatusCode == HttpStatusCode.Redirect || resp.StatusCode == HttpStatusCode.TemporaryRedirect) 
          { 
           string redirectUrl = resp.Headers.Location.ToString(); 

           if (redirectUrl.Contains("vme-store")) 
           { 

            redirectUrl = redirectUrl.Replace("vme-store", "10.230.0.11"); 
           } 
           content.Dispose(); 
           return await HttpPut(redirectUrl, inFilePath); 
         } 

また、あなたはおそらく、あなたがスタックトレースに深く進む前に、すべてのリソースが解放されることを保証するために、HTTP応答のような他のIDisposableをオブジェクトを処分したいと思います。これは再帰の1つの問題です。Usingステートメントを使用している間にスコープを離れることはないので、仕事をしていないことになります。

+0

私は尋ねる前にそれを試したが、今はcontent.Dispose()を追加して試してみた。再帰呼び出しの前に。それは助けにはなりません:/また、私たちのローカルtestenvironmentでコードを実行するとき、私は再帰呼び出しを起動しません – CeeRo

+0

ストリームは要求を得るために開いている必要があります、それはまたFileStreamではありません。 – Marco

+0

@Despertar:引用:これは再帰での1つの問題です。使用するステートメントを使用している間にスコープを離れることなく、自分の仕事をしていないということです。 おかげさまで、ありがとうございます。しかし、私が言ったように、私は私のローカル環境でそれを実行するときに再帰呼び出しを発してif文を入力することはありませんが、私は同じ結果を得ています – CeeRo

0
using (HttpResponseMessage resp = await client.SendAsync(req)) 

あなたがたFileStreamのロックを共有しますので、この行は、多分あなたはそれを行うことができない、新しいスレッドコンテキストしたがって、その実行のための新しいコンテキストを作成するようです。

+0

そこにはありますが、応答をつかむ周りに方法はありません? あなたが使用している部分について考えているなら、私は実際にその例外を取得してから、すべてを破棄していることを確認してからそれを投げました – CeeRo

+0

あなたはそれについて考えると、あなたは非同期関数を使用していますが、それでも実行をブロックしているので、それを使用しています。あなたがそうでないコールバックを使用している場合、私は理解するでしょう。 – Marco

+0

私が正しく理解していれば、await-statementsは、作業中に呼び出し元に制御を戻します。これは、アップロードがサーバー上の何かをブロックする方法がないことを確認する試みでした。私はそれについてのすべてを正しく理解したとは確信していませんが、私はまだ非常に新人です。あなたの更新については、私はすぐにそれを把握していない場合は、私はhttpwebresponse/HttpClientの代わりに要求に切り替える必要があると思う。私はどのくらい簡単にHttp PUTがそこにあるかわからないのですか? – CeeRo

関連する問題