C# HttpClient METTRE
Pour une raison quelconque, mon code ci-dessous que l'habitude de travailler maintenant donc lève une exception:
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();
}
}
}
}
}
}
L'exception que j'obtiens est:
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:
Je vais avoir un moment très difficile de trouver une bonne documentation et des exemples pour HttpClient, et j'ai du mal à comprendre pourquoi ce soudain ne fonctionne pas (totalement méthode similaire avec StringContent au lieu de StreamContent fonctionne parfaitement)...
L'origine est appelée à partir de son propre thread, et ensuite comme ceci:
public static async void VmeUploadMedia(string inUploadLink, string inFilePath)
{
string result = await HttpConnector.HttpPut(inUploadLink, inFilePath);
}
Quelqu'un spot rien d'évident?
Grâce
Mise à JOUR
S'avère que l'obtention de l'expo-les gars de leur carte de stockage-nom avec IP afin que je puisse revenir à mon code d'origine est la meilleure solution. Le problème que j'ai est quelque chose à voir avec AllowAutoRedirect = false. L'exception s'est produite sur HttpResponseMessage resp = attendent le client.SendAsync(req.), même si il n'y a pas de redirection qui se passe vraiment. Je suis un peu perdu quant à pourquoi il était encore passe, mais en utilisant ce code tout fonctionne maintenant:
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();
}
}
}
}
}
Merci aux gens qui essayaient d'aider les
Bon point, le faire maintenant
Pourriez-vous maintenant, ne pas utiliser de l'PutAsJsonAsync<>?
OriginalL'auteur CeeRo | 2013-04-08
Vous devez vous connecter pour publier un commentaire.
S'avère que l'obtention de l'expo-les gars de leur carte de stockage-nom avec IP afin que je puisse revenir à mon code d'origine est la meilleure solution. Le problème que j'ai est quelque chose à voir avec AllowAutoRedirect = false. L'exception s'est produite sur HttpResponseMessage resp = attendent le client.SendAsync(req.), même si il n'y a pas de redirection qui se passe vraiment. Je suis un peu perdu quant à pourquoi il était encore passe, mais en utilisant ce code tout fonctionne maintenant:
Merci aux gens qui essayaient d'aider les
OriginalL'auteur CeeRo
Il semble que cette ligne va créer un nouveau contexte pour que l'exécution, d'où un nouveau contexte de thread, peut-être que vous ne pouvez pas le faire, parce que vous allez partager la serrure de la FileStream.
Si vous pensez à ce sujet, ce code est à peu près inutile de la façon dont vous utilisez, parce que vous utilisez une fonction async, mais vous avez encore bloquer l'exécution, je comprendrais si vous utilisez un rappel qui n'est pas le cas.
Si j'ai bien compris l'attendent-états envoie le contrôle à l'appelant pendant le travail, il est une tentative de s'assurer qu'il y a pas moyen de l'upload serait de bloquer quoi que ce soit sur le serveur. Je ne suis pas sûr que j'ai tout compris à ce sujet correctement, je suis encore qu'un débutant. Pour votre mise à jour, oui, je pense que je vais devoir passer à httpwebresponse/demande à la place de HttpClient si je n'ai pas le découvrir bientôt. Je ne suis pas sûr de savoir comment facile Http PUT est-il bien?
using (HttpResponseMessage resp = await client.SendAsync(req))
Il semble que cette ligne va créer un nouveau contexte pour que l'exécution, d'où un nouveau contexte de thread, peut-être que vous ne pouvez pas le faire. Puis-je utiliser quelque chose comme [lien]msdn.microsoft.com/en-us/library/... pour cela? Ou est ma façon de penser à cette chose entière quand il s'agit de threads et asynchroneAvez-vous essayer de remplacer ainsi le code avec celui que j'ai fournies dans la section "mise à jour" juste pour s'assurer que le problème ne vient pas de là?
OriginalL'auteur MeTitus
Il semble que vous appelez
HttpPut()
de nouveau, mais vous avez encore laFileStream
ouvert. Essayez de jeter le FileStream avant de vous récursive appelHttpPut()
de l'intérieur de lui-même.En outre, vous serait probablement voulez vous débarrasser de tout autre IDisposable des objets, comme la réponse http pour s'assurer que toutes les ressources sont libérées avant de poursuivre plus en profondeur de la trace de la pile. C'est un problème avec la récursivité, que pendant que vous utilisez
Using
états-vous de ne pas quitter leur portée, de sorte qu'ils ne font pas leur travail.Le flux doit être ouvert pour obtenir à la demande, aussi il n'est pas un FileStream.
Citation: C'est un problème avec la récursivité, que pendant que vous utilisez à l'Aide des états-vous de ne pas quitter leur portée, de sorte qu'ils ne font pas leur travail. C'est utile à savoir, merci. Mais comme je l'ai dit, je n'entrez jamais dans le if de tir à l'appel récursif lors de l'exécution dans notre environnement local, et encore j'obtiens le même résultat
Pouvez-vous vérifier si le problème se produit sans recurrsion. Supprimer l'appel intérieur à
HttpPut()
et voir si vous pouvez le reproduire. Si vous ne pouvez pas puis au moins ça donne un gros indice pour savoir où se trouve le problème. @Marco Regardez cette ligneusing (var content = new StreamContent(new FileStream(inFilePath, FileMode.Open)))
.C'est génial! Au lieu d'ajouter la solution à votre question, vous pouvez le mettre comme une réponse à votre propre question, puis de le marquer comme " la accepté de répondre. Cela aidera les gens dans l'avenir le trouver plus vite s'ils ont un problème similaire.
OriginalL'auteur Despertar