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.