【问题标题】:Why CsvHelper not reading from MemoryStream?为什么 CsvHelper 不从 MemoryStream 读取?
【发布时间】:2018-03-22 17:27:24
【问题描述】:

我正在尝试将上传的 csv 文件转换为对象,这样我就可以保存在数据库中。 在控制器中我使用的是 CsvHeler

但看起来这只有在我首先保存文件并从中读取时才有效。 CsvHelper 无法直接从内存流中处理文件内容。在下面的代码中,第一个 GetRecords 返回空

    [HttpPost]
    [Route(ApiRoutes.EodVariationMarginPlugs)]
    public async Task<IActionResult> UploadPlugAsync(IFormFile filePayload)
    {

        if (filePayload.Length > 0)
        {

            using (var stream = new MemoryStream())
            {
                filePayload.CopyTo(stream);
                using (var reader = new StreamReader(stream))
                using (var csv = new CsvReader(reader))
                {
                    csv.Configuration.RegisterClassMap<EodVariationMarginPlugMap>();
                    csv.Configuration.MissingFieldFound = null;
                    var records = csv.GetRecords<EodVariationMarginPlug>().ToList(); // record count is 0
                    foreach (var p in records)
                    {
                        p.CreatedAt = DateTimeOffset.Now;
                        p.CreatedBy = HttpContext.User.Identity.Name;
                    }
                    await _repository.InsertPlugsAsync(records);
                }
            }

        var fileName = ContentDispositionHeaderValue
            .Parse(filePayload.ContentDisposition)
            .FileName.ToString().Trim('"');
            var path = Path.Combine(Path.GetTempPath(), fileName);
            using (var fileStream = new FileStream(path, FileMode.Create))
            {
                await filePayload.CopyToAsync(fileStream);
            }
            var textReader = System.IO.File.OpenText(path);
            using (var csv = new CsvReader(textReader))
            {
                csv.Configuration.RegisterClassMap<EodVariationMarginPlugMap>();
                csv.Configuration.MissingFieldFound = null;
                var records = csv.GetRecords<EodVariationMarginPlug>().ToList();
                foreach (var p in records)
                {
                    p.CreatedAt = DateTimeOffset.Now;
                    p.CreatedBy = HttpContext.User.Identity.Name;
                }
                await _repository.InsertPlugsAsync(records);
            }
        }
        return Ok();
    }

【问题讨论】:

  • 您可能需要刷新流并将其返回到开头。
  • 谢谢@Amy,我以为就这样了,所以我在filePayload.CopyTo(stream); 之后添加了stream.Position = 0;,但CsvHelper 并没有从MemoryStream 中得到任何东西

标签: asp.net-core csvhelper


【解决方案1】:

这里最常见的错误是忘记MemoryStream 是二进制的;它以字节为单位。你需要一些处理字符的东西。好消息是您通过将MemoryStream 包装在StreamReader 中来避免该错误:

using (var reader = new StreamReader(stream))

StreamReader 实现了TextReader,它适用于字符而不是字节。耶!坏消息是 StreamReader 是在这一行之后创建的:

filePayload.CopyTo(stream);

问题在于流中的那条线指向了数据的end。当您尝试从中读取时,流中没有任何内容。

解决此问题所需要做的就是回到起点。所以这个:

using (var stream = new MemoryStream())
{
    filePayload.CopyTo(stream);
    using (var reader = new StreamReader(stream))

变成这样:

using (var stream = new MemoryStream())
{
    filePayload.CopyTo(stream);
    stream.Seek(0, SeekOrigin.Begin);

    using (var reader = new StreamReader(stream))

【讨论】:

  • Joel Coehoorn - 非常感谢!
  • 在 2019 年也为我工作,只是 stream.Seek(0, SeekOrigin.Begin); 的行,然后将我的 memoryStream 传递给 new csvReader(ms)。谢谢乔尔
猜你喜欢
  • 2022-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多