出于某种原因,我之前可以正常工作的下面代码现在会导致异常:
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而不是StreamContent的完全类似方法可以完美地工作)...
最初它从自己的线程调用,然后像这样:
public static async void VmeUploadMedia(string inUploadLink, string inFilePath)
{
string result = await HttpConnector.HttpPut(inUploadLink, inFilePath);
}
有人发现了什么明显的问题吗?
谢谢
更新
结果发现让expo的人将他们的存储名称与其IP进行映射,以便我可以回到原来的代码是最好的解决方法。我遇到的问题与AllowAutoRedirect = false有关。即使没有实际重定向,HttpResponseMessage resp = await client.SendAsync(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();
}
}
}
}
}
感谢那些一直在努力帮忙的人