System.ObjectDisposedException:无法访问已处置的对象。对象名称:“无法访问关闭的文件”。

时间:2019-09-18 06:51:29

标签: c# asp.net-core-webapi

我正在使用Web API核心,并返回IActionResult。我的API之一在返回FileResult时抛出错误。

我收到以下错误消息。

  

System.ObjectDisposedException:无法访问已处置的对象。   对象名称:“无法访问已关闭的文件。”

我的代码类似于:

FileStream zipToOpen;

using (zipToOpen = new FileStream(Path.Combine(reportsPath, Guid.NewGuid().ToString()) + ".zip", FileMode.Create))
{
    using (ZipArchive zipArchive = new ZipArchive(zipToOpen, ZipArchiveMode.Create, true))
    {
        foreach (var document in documents)
        {
            string fileName = string.Empty;
            int index = document.Path.LastIndexOf("/");
            if (index != -1)
                fileName = document.Path.Substring(index + 1);
            zipArchive.CreateEntryFromFile(document.Path, fileName);                            
        }
    }

    //zipToOpen.Position = 0;
    return File(zipToOpen, "application/zip", "MyDocuments.zip");
}

任何人都可以帮助我解决什么问题。

2 个答案:

答案 0 :(得分:0)

您正在使用流,因此在刷新或关闭流之前,仍然需要像ZipArchive这样的组件。问题是您要在using底线所在的zipArchive语句之外返回流。如果将退货单移到该using块内,就可以了。

答案 1 :(得分:0)

如另一个答案中所述,在框架有时间完成其功能之前,将废弃文件流。这是因为您将在using块中返回流,一旦超出范围,该块将对其进行处理。

如果不需要将存档实际保存/写入磁盘,请考虑在内存中构建存档并返回其流。

//...

MemoryStream zipStream = new MemoryStream();
using (var zipArchive  = new ZipArchive(zipStream, ZipArchiveMode.Create, leaveOpen: true)) {
    foreach (var document in documents) {
        string fileName = document.Path;
        int index = fileName.LastIndexOf("/");
        if (index != -1)
            fileName = fileName.Substring(index + 1);
        zipArchive.CreateEntryFromFile(document.Path, fileName);
    } 
} // disposal of archive will force data to be written to memory stream.
zipStream.Position = 0; //reset memory stream position.
return File(zipStream, "application/zip", "MyDocuments.zip");

请注意,FileResult处理完后将由 PREFIX : <http://www.semanticweb.org/evangelos/ontologies/2019/2/untitled-ontology-2#> SELECT ?property ?value WHERE{ ?poi :POIhasID 7878787. ?poi ?property ?value; filter (?property not in (rdf:type)) #filter isLiteral(?value) } 处理。