Asp.net-Core
為什麼 CsvHelper 不從 MemoryStream 讀取?
我正在嘗試將上傳的 csv 文件轉換為對象,因此我可以保存在 db 中。在控制器中我使用 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(); }
這裡最常見的錯誤是忘記
MemoryStream二進制;它以字節為單位。你需要一些涉及角色的東西,這並不總是 1:1 的改編。MemoryStream好消息是您通過將a包裝起來避免了該錯誤StreamReader:using (var reader = new StreamReader(stream))
StreamReaderimplementsTextReader,它適用於字元而不是字節。耶!壞消息是 StreamReader 是在這一行之後創建的:filePayload.CopyTo(stream);問題是那條線離開了指向數據末尾的流。當您嘗試從中讀取時,流中沒有任何內容。
要解決此問題,您需要做的就是回到起點。所以這:
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))