J'ai un projet universel Windows avec plusieurs appels API. Une méthode refuse de fonctionner même si mes autres appels fonctionnent parfaitement comme ça. J'ai essayé le mot clé using
, pensant que cela résoudrait le problème.
La fonction:
public async Task<User> GetNewUser(string user_guid, OAuthTokens OAuth)
{
String userguidJSON = VALIDJSON_BELIEVE_ME;
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", Encrypt(OAuth.Accesstoken));
using (HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, BASE_URL + URL_USERS + "/data"))
{
req.Content = new StringContent(userguidJSON, Encoding.UTF8, "application/json");
await httpClient.SendAsync(req).ContinueWith(respTask =>
{
Debug.WriteLine(req.Content.ReadAsStringAsync()); //Error is thrown ono this line
});
return null;
}
}
}
MODIFIER
public async Task<User> GetNewUser(string user_guid, OAuthTokens OAuth)
{
String userguidJSON = VALIDJSON_BELIEVE_ME;
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", Encrypt(OAuth.Accesstoken));
using (HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, BASE_URL + URL_USERS + "/data"))
{
req.Content = new StringContent(userguidJSON, Encoding.UTF8, "application/json");
await httpClient.SendAsync(req);
var result = await req.Content.ReadAsStringAsync(); //Cannot access a disposed object. Object name: 'System.Net.Http.StringContent'.
Debug.WriteLine(result);
return null;
}
}
}
Le stacktrace
at System.Net.Http.HttpContent.CheckDisposed()
at System.Net.Http.HttpContent.ReadAsStringAsync()
at Roadsmart.Service.RoadsmartService.<GetNewUser>d__2e.MoveNext()
--- 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 Roadsmart.ViewModel.SettingsPageViewModel.<SetNewProfilePicture>d__1e.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__3(Object state)
at System.Threading.WinRTSynchronizationContext.Invoker.InvokeCore()
ObjectDisposedException
est levée car vous supprimez HttpRequestMessage
et HttpClient
avant la fin de req.Content.ReadAsStringAsync()
.
Notez que req.Content.ReadAsStringAsync()
est une méthode asynchrone. Vous devez attendre qu'il se termine avant de supprimer le HttpClient
.
De plus, vous semblez appeler ReadAsStringAsync
dans req.Content
, cela ne devrait-il pas être response.Content
?
using (HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, BASE_URL + URL_USERS + "/data"))
{
req.Content = new StringContent(userguidJSON, Encoding.UTF8, "application/json");
var response = await httpClient.SendAsync(req);
var result = await response.Content.ReadAsStringAsync();//await it
Debug.WriteLine(result);
return null;
}
Il n'y a presque aucune raison d'utiliser ContinueWith
pour traiter async/wait. Tout cela est fait par le compilateur pour vous.
La vraie raison pour laquelle le ObjectDisposedException
est levé est que le HttpClient
supprime le Content
immédiatement après une requête terminée. Jetez un oeil à la docs .
Donc, si vous avez besoin de lire le contenu d'un Request
, par exemple dans des tests, assurez-vous de le lire avant d'appeler SendAsync
.
Vous accédez au contenu de la demande, pas à la réponse.
Ce
await httpClient.SendAsync(req);
var result = await req.Content.ReadAsStringAsync(); //Cannot access a disposed object. Object name: 'System.Net.Http.StringContent'.
devrait être
var response = httpClient.SendAsync(req);
var result = await response.Content.ReadAsStringAsync();