You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用ReadAsStringAsync时触发System.ObjectDisposedException问题

问题:调用HttpResponseMessage.ReadAsStringAsync()时抛出ObjectDisposedException异常

现象

调用HttpClient.GetAsync()获取响应后,读取Content属性内容时始终抛出System.ObjectDisposedException,预期应返回JSON字符串。即使将HttpClient构造函数的disposeHandler设为false也无法解决该问题。

补充说明

调用Nextcloud API时,返回200响应时一切正常,但返回401 Unauthorized时触发该异常。已编写NetworkException()方法处理异常并抛出自定义异常,但在该方法中调用ReadAsStringAsync()时同样报错。

相关代码

internal async Task<T> HandleMessage<T>(HttpResponseMessage message)
{
    string jsonContent = await message.Content.ReadAsStringAsync(); // 报错行
    return JsonConvert.DeserializeObject<T>(jsonContent); 
}
internal async Task<T> GetRequest<T>(string route)
{
    var response = await _httpClient.GetAsync(new Uri(_baseUrl, route));
    try
    {
        response.EnsureSuccessStatusCode();
    }
    catch (HttpRequestException eax) // HTTP错误触发
    {
        await NetworkException(route, response, eax);  
    }
    return await HandleMessage<T>(response);
}
internal async Task NetworkException(string route, HttpResponseMessage message, HttpRequestException innerEx)
{
    var ms = await message.Content.ReadAsStringAsync(); // 报错行
    throw new SiliconNetworkException($"Unknown Network Error occured trying to connect to {route}. See Inner Exception for more information",
        innerEx,
       JsonConvert.DeserializeObject<SiliconOCSResponse<List<string>>>(ms)
        );
}

堆栈跟踪

at System.Net.Http.HttpContent.CheckDisposed()
   at System.Net.Http.HttpContent.ReadAsStringAsync()
   at SiliconCloud.Network.SiliconNetwork.<NetworkException>d__22.MoveNext() in C:\Users\Weasel\source\repos\Silicon\SiliconCloud\Network\SiliconNetwork.cs:line 233
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at SiliconCloud.Network.SiliconNetwork.<GetRequest>d__16`1.MoveNext() in C:\Users\Weasel\source\repos\Silicon\SiliconCloud\Network\SiliconNetwork.cs:line 174
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at SiliconCloud.UserManagement.UserProvisioning.SiliconUserInstruction.<GetAllUsers>d__17.MoveNext() in C:\Users\Weasel\source\repos\Silicon\SiliconCloud\UserManagement\UserProvisioning\SiliconUserInstruction.cs:line 278

解决方案

问题根源

HttpContent对象只能被读取一次,读取完成后会被标记为已消耗/释放。当前代码中,401异常触发后,NetworkException方法会先读取一次响应内容,而catch块执行完毕后,代码还会继续执行return await HandleMessage<T>(response);,再次尝试读取已被消耗的HttpContent,从而抛出ObjectDisposedException。

修复方案1:终止异常后的后续流程

在catch块处理完异常后,添加throw语句确保后续代码不再执行,避免重复读取响应内容:

internal async Task<T> GetRequest<T>(string route)
{
    var response = await _httpClient.GetAsync(new Uri(_baseUrl, route));
    try
    {
        response.EnsureSuccessStatusCode();
    }
    catch (HttpRequestException eax)
    {
        await NetworkException(route, response, eax);
        // 强制抛出,确保后续代码不执行
        throw;
    }
    return await HandleMessage<T>(response);
}

修复方案2:提前缓存响应内容

在判断响应状态码之前,先一次性读取响应内容并缓存,后续无论成功还是失败都复用该内容,彻底避免重复读取的问题:

internal async Task<T> GetRequest<T>(string route)
{
    var response = await _httpClient.GetAsync(new Uri(_baseUrl, route));
    // 提前读取响应内容并缓存
    string content = await response.Content.ReadAsStringAsync();
    
    try
    {
        response.EnsureSuccessStatusCode();
        return JsonConvert.DeserializeObject<T>(content);
    }
    catch (HttpRequestException eax)
    {
        throw new SiliconNetworkException($"调用 {route} 时发生未知网络错误,详见内部异常",
            eax,
            JsonConvert.DeserializeObject<SiliconOCSResponse<List<string>>>(content));
    }
}

这个方案还能简化代码结构,不需要单独的HandleMessage和NetworkException方法,减少冗余。

内容的提问来源于stack exchange,提问作者exafile

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 11:05:15