2013-04-08 14 views
8

डाल कि अब काम करता था किसी कारण मेरी नीचे कोड के लिए फलस्वरूप एक अपवाद को जन्म देती है:सी # 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 के लिए उचित दस्तावेज़ीकरण और उदाहरण ढूंढने में कठिन समय, और मैं यह पता लगाने के साथ संघर्ष कर रहा हूं कि यह अचानक क्यों काम नहीं करता है (स्ट्रीमकंटेंट की बजाय स्ट्रिंगकंटेंट के साथ पूरी तरह से समान विधि पूरी तरह से काम करता है) ...

यह मूल रूप से अपने आप धागे से बुलाया जाता है, और उसके बाद इस तरह:

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

किसी को भी स्थान कुछ भी स्पष्ट?

धन्यवाद

अद्यतन

उनके भंडारण-नाम के साथ यह आईपी तो मैं वापस अपने मूल कोड को जा सकते हैं सबसे अच्छा समाधान थी मैप करने के लिए हो रही एक्सपो-लोग बाहर कर देता है। मेरी समस्या यह थी कि AllowAutoRedirect = false के साथ कुछ करना है। HttpResponseMessage resp = पर प्रतीक्षा करने का अपवाद। SendAsync (req), भले ही कोई पुनर्निर्देशन वास्तव में नहीं चल रहा हो। मैं एक तरह से कारण है कि यह भी हो रहा था, लेकिन इस कोड सब कुछ का उपयोग करने के रूप में खो रहा हूँ अब काम कर रहा है: जो मदद करने के लिए

+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

एक्सपो-लोगों को अपने आईपी के साथ अपने स्टोरेज-नाम को मैप करने के लिए बाहर निकलता है ताकि मैं अपने मूल कोड पर वापस जा सकूं, सबसे अच्छा समाधान था। मेरी समस्या यह थी कि AllowAutoRedirect = false के साथ कुछ करना है। HttpResponseMessage resp = पर प्रतीक्षा करने का अपवाद। SendAsync (req), भले ही कोई पुनर्निर्देशन वास्तव में नहीं चल रहा हो। मैं एक तरह से कारण है कि यह भी हो रहा था, लेकिन इस कोड सब कुछ का उपयोग करने के रूप में खो रहा हूँ अब काम कर रहा है: जो मदद करने के लिए

+0

मदद करने की कोशिश करने के लिए धन्यवाद :) यह सब अच्छा है – dmportella

0

ऐसा लगता है कि आप HttpPut() बुला रहे हैं कोशिश कर रहे थे लोगों के लिए

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(); 
        } 
       } 
      } 
     } 
    } 

धन्यवाद दोबारा, लेकिन आपके पास अभी भी FileStream खोला गया है। आप पहले से ही HttpPut() पर कॉल करने से पहले फ़ाइलस्ट्रीम का निपटान करने का प्रयास करें।

//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 वस्तुओं के निपटान के लिए यह सुनिश्चित करें कि सभी संसाधनों को मुक्त कर दिया जाता है इससे पहले कि आप स्टैक ट्रेस में गहरी आगे बढ़ना चाहते हैं। यह रिकर्सन के साथ एक समस्या है, कि जब आप Using कथन का उपयोग कर रहे हैं तो आप अपना दायरा नहीं छोड़ रहे हैं, इसलिए वे अपना काम नहीं कर रहे हैं।

+0

मुझे पूछने से पहले कोशिश की जानी चाहिए, लेकिन मैंने सामग्री जोड़कर इसे आजमाया। उद्देश्य(); रिकर्सिव कॉल से पहले; इससे मदद नहीं मिली:/साथ ही, हमारे स्थानीय टेस्टेनवायरमेंट में कोड चलाते समय मैंने कभी भी रिकर्सिव कॉल – CeeRo

+0

को आग नहीं दी, अनुरोध प्राप्त करने के लिए स्ट्रीम खुली होनी चाहिए, यह फ़ाइलस्ट्रीम भी नहीं है। – Marco

+0

@ डिस्परटर: उद्धरण: यह रिकर्सन के साथ एक समस्या है, कि जब आप कथन का उपयोग कर रहे हैं तो आप अपना दायरा नहीं छोड़ रहे हैं, इसलिए वे अपना काम नहीं कर रहे हैं। यह जानने के लिए उपयोगी है, धन्यवाद। लेकिन जैसा कि मैंने कहा, मैंने कभी भी हमारे स्थानीय माहौल में इसे चलाने के दौरान रिकर्सिव कॉल को फायरिंग करने वाले आई-स्टेटमेंट में प्रवेश नहीं किया है, और फिर भी मुझे एक ही परिणाम मिल रहा है – CeeRo

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

ऐसा लगता है कि इस लाइन है, इसलिए एक नया धागा संदर्भ कि निष्पादन के लिए एक नया संदर्भ पैदा करेगा, शायद आप ऐसा नहीं कर सकते, क्योंकि आप FileStream का ताला साझा करेंगे।

+0

प्रतिक्रिया के आसपास कोई रास्ता नहीं है, हालांकि वहां है? यदि आप उपयोग-भाग के बारे में सोच रहे हैं, तो मैंने वास्तव में उस अपवाद को शुरू करने के बाद वहां पर फेंक दिया ताकि यह सुनिश्चित किया जा सके कि मैंने सबकुछ – CeeRo

+0

का निपटारा किया है, यदि आप इसके बारे में सोचते हैं, तो यह कोड आपके जैसा तरीका बेकार है इसका उपयोग कर रहे हैं, क्योंकि आप एसिंक फ़ंक्शन का उपयोग करते हैं लेकिन फिर भी आप निष्पादन को अवरुद्ध करते हैं, तो मैं समझूंगा कि क्या आप कॉलबैक का उपयोग कर रहे हैं जो मामला नहीं है। – Marco

+0

यदि मैं सही ढंग से समझ गया हूं कि प्रतीक्षा-वक्तव्य कॉल करते समय कॉलर को वापस भेजता है, तो यह सुनिश्चित करने का प्रयास था कि अपलोड सर्वर पर कुछ भी अवरुद्ध नहीं करेगा। मुझे यकीन नहीं है कि मैं इसके बारे में सबकुछ ठीक से समझ गया हूं, हालांकि, मैं अभी भी बहुत रूकी हूं। आपके अपडेट के अनुसार, हाँ मुझे लगता है कि मुझे एचटीपी क्लाइंट के बजाय httpwebresponse/अनुरोध पर स्विच करना होगा यदि मुझे जल्द ही पता नहीं चलता है। मुझे यकीन नहीं है कि एचटीपी पुट कितना आसान है? – CeeRo