6

在我正在创建的商业应用程序中,我们允许管理员上传包含某些数据的 CSV 文件,这些数据会被解析并输入我们的数据库(正在发生所有适当的错误处理等)。

作为升级到 .NET 4.5 的一部分,我不得不更新这段代码的一些方面,并且在我这样做的同时,我遇到了一个使用 MemoryStream 处理上传文件而不是临时保存到的人的答案文件系统。我没有真正的理由去改变(也许它甚至是不好的),但我想试一试来学习一下。因此,我迅速换掉了这段代码(由于上传了其他元数据,从强类型模型中):

HttpPostedFileBase file = model.File;
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/Uploads"), fileName);
file.SaveAs(path);

CsvParser csvParser = new CsvParser();
Product product = csvParser.Parse(path);

this.repository.Insert(product);
this.repository.Save();

return View("Details", product);

对此:

using (MemoryStream memoryStream = new MemoryStream())
{
    model.File.InputStream.CopyTo(memoryStream);

    CsvParser csvParser = new CsvParser();
    Product product = csvParser.Parse(memoryStream);

    this.repository.Insert(product);
    this.repository.Save();

    return View("Details", product);
}

不幸的是,当我这样做时,事情就中断了——我的所有数据都带有空值,而且 MemoryStream 中似乎实际上没有任何内容(尽管我对此并不积极)。我知道这可能是一个很长的镜头,但是有什么明显的东西我在这里遗漏了,或者我可以做些什么来更好地调试它?

4

2 回答 2

6

您需要添加以下内容:

model.File.InputStream.CopyTo(memoryStream);
memoryStream.Position = 0;

...

Product product = csvParser.Parse(memoryStream);

当您将文件复制到 MemoryStream 中时,指针将移动到流的末尾,因此当您尝试读取它时,您将得到一个空字节而不是流数据。您只需要将位置重置为起点,即 0。

于 2013-04-02T21:40:57.700 回答
2

我相信的问题是你的 memoryStream 的位置设置到最后,我猜你的 CSVParser 只是从那一点开始处理,没有数据。

要解决此问题,您只需在使用 csvParser 解析它之前将 memoryStream 位置设置为 0。

memoryStream.Position = 0;
于 2013-04-02T21:41:40.867 回答