ObjectDisposedException на HttpClient
у меня есть универсальный проект Windows с несколькими вызовами API.
Один метод отказывается работать, хотя мои другие вызовы работают отлично.
Я пробовал using
ключевое слово думал, что это решит проблему.
функции:
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;
}
}
}
редактировать
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;
}
}
}
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()
3 ответов
ObjectDisposedException
бросается, потому что вы избавляетесь от HttpRequestMessage
и HttpClient
до req.Content.ReadAsStringAsync()
заканчивается.
отметим, что req.Content.ReadAsStringAsync()
- это асинхронный метод. Вам нужно дождаться его завершения, прежде чем размещать HttpClient
.
кроме того, вы, кажется, звоните ReadAsStringAsync
на req.Content
, это не должно быть 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;
}
почти нет причин использовать ContinueWith
при работе с async / await. Все, что делает компилятор для вас.
вы получаете доступ к содержимому запроса, а не к ответу.
этой
await httpClient.SendAsync(req);
var result = await req.Content.ReadAsStringAsync(); //Cannot access a disposed object. Object name: 'System.Net.Http.StringContent'.
должно быть
var response = httpClient.SendAsync(req);
var result = await response.Content.ReadAsStringAsync();
фактическая причина ObjectDisposedException
бросается, потому что HttpClient
распоряжается Content
сразу после завершения запроса. Взгляните на docs.
Итак, если вам нужно прочитать Request
содержание, например, в тестах, не забудьте прочитать его до вызов SendAsync
.