Object is disposed after PostAsync with HttpClient

2019-04-07 22:13发布

问题:

I'm trying to send a file with HttpClient and if something on the receiving side fails I want to resend the same file stream.

I'm creating a post request with a MultipartFormDataContent, which contains the stream. Everything looks fine when I call PostAsync for the first time. But when I try to repeat the request I get System.ObjectDisposedException.

My file stream is disposed after the first call of PostAsync... Why and is there a solution to my problem?

Here is basic example of what am I talking about.

    public ActionResult Index()
    {
        var client = new HttpClient { BaseAddress = new Uri(Request.Url.AbsoluteUri) };

        var fi = new FileInfo(@"c:\json.zip");

        using (var stream = fi.OpenRead())
        {
            var content = new MultipartFormDataContent();
            var streamContent = new StreamContent(stream);
            streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
            streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
            {
                FileName = "\"File\""
            };

            content.Add(streamContent);

            var isSuccess = client.PostAsync("Home/Put", content).
                ContinueWith(x => x.Result.Content.ReadAsAsync<JsonResponse>().Result.Success).Result;
            //stream is already disposed

            if (!isSuccess)
            {
                isSuccess = client.PostAsync("Home/Put", content).
                    ContinueWith(x => x.Result.Content.ReadAsAsync<JsonResponse>().Result.Success).Result;
            }
        }

        return View();
    }

    public JsonResult Put(HttpPostedFileBase file)
    {
        return Json(new JsonResponse { Success = false });
    }

回答1:

If you call LoadIntoBufferAsync on the Content object it will copy the file stream into a memorystream inside the StreamContent object. This way, disposing the HttpContent should not close your FileStream. You will need to reposition the stream pointer and create a new StreamContent to make the second call.