Why CsvHelper not reading from MemoryStream?

本小妞迷上赌 提交于 2020-03-18 11:51:10

问题


I am trying to convert an uploaded csv file to an object, so i can save in db. In the controller I am using CsvHeler

But looks like this only works if I first save the file and read from it. CsvHelper is not able to process the file contents directly from memory stream. In the code below the first GetRecords returns empty

    [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();
    }

回答1:


MemoryStream is binary. It deals in bytes. You need something that deals in characters. The good news is you attempted that; you have this:

using (var reader = new StreamReader(stream))

StreamReader implements TextReader, which works with characters rather than bytes. Yay! The bad news is the StreamReader is created right after this line:

filePayload.CopyTo(stream);

The problem was that line left the stream pointed at the end of the data. When you try to read from it, there's nothing left in the stream.

All you should need to do to fix this is seek back to the beginning. So this:

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

Becomes this:

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

    using (var reader = new StreamReader(stream))


来源:https://stackoverflow.com/questions/49434920/why-csvhelper-not-reading-from-memorystream

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!