【问题标题】:Exception while posting to web API, HTTPClient already disposed发布到 Web API 时出现异常,HTTPClient 已释放
【发布时间】:2018-04-02 11:36:58
【问题描述】:

我将一个字节数组从 Xamarin.Forms 中的 Android 应用程序发布到 .NET Core 2.0 WebAPI。但是,我收到一个异常,说 NetworkStream 已经被释放;

发出请求的代码;

public async Task PostImageAsync(ImageDTO image)
{
    var content = new MultipartFormDataContent();
    var byteArrayContent = new ByteArrayContent(image.Content);
    content.Add(byteArrayContent, image.FileTile, image.FileName);

    try
    {
        using (var httpClient = GetNewHttpClient())
        {
            SetBearerToken(httpClient);

            var response = await httpClient.PostAsync($"{_apiUrl}/api/images/upload", content);
            if (response.IsSuccessStatusCode)
            {

            }
            else
            {

            }
        }
    }
    catch (Exception e)
    {
        //Exception occurs here
        var msg = e.GetBaseException().Message;

        throw;
    }
}

获取 HttpClient 的代码

private HttpClient GetNewHttpClient()
{
     //HttpClientHandler is a global variable                
     var httpClient = new HttpClient(HttpClientHandler, false) {BaseAddress = new Uri(_apiUrl)};

    return httpClient;
}

API 端点

[HttpPost]
public async Task<IActionResult> Upload(IFormFile file)
{
    if (file == null || file.Length == 0) return BadRequest();

    return Ok();
}

编辑 - SetBearerToken 方法

private static void SetBearerToken(HttpClient client)
        {
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", App.StoredToken);
        }

例外情况:

cannot access a disposed object. Object name: 'System.Net.Sockets.NetworkStream'.

感觉我在这里犯了一个非常明显的错误,但我无法理解它。有人有什么想法吗?

【问题讨论】:

  • 在此调用之前是否使用了HttpClientHandler
  • SetBearerToken 中发生了什么?
  • @CamiloTerevinto,不,这是 API 中第一个也是唯一一个使用它的方法
  • @Seb,我会用那个方法更新问题

标签: c# asp.net-web-api


【解决方案1】:

不要丢弃HttpClient

https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/

还注意到您将_apiUrl 设置为BaseAddress 并在帖子中为网址添加前缀。选择一个或另一个。

【讨论】:

  • 谢谢,我会调查一下
  • 你必须处理掉HttpClient,这是完全错误的。
【解决方案2】:

不要在异步函数中释放对象

异步方法中的 using 语句是“奇怪的”,因为 Dispose call 可能在与获取的线程不同的线程中执行 资源(取决于同步上下文等),但它仍然会 发生...假设您正在等待的东西曾经出现或 失败,当然。 (就像你最终不会打电话给Dispose 如果您的 using 语句包含对方法的调用,则为非异步代码 永远不会回来。)

@jon-skeet https://stackoverflow.com/a/16566605/2228916

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-10
    相关资源
    最近更新 更多