【问题标题】:How to parse CSV via CSV Helper to my custom class IFormFile .Net Core c#如何通过 CSV Helper 将 CSV 解析为我的自定义类 IFormFile .Net Core c#
【发布时间】:2021-01-18 22:04:14
【问题描述】:

我正在将 CSV 文件从客户端上传到 .NET CORE Web Api 应用程序。

我正在使用 CsvHelper .net 库。

我成功接收文件,我想将其解析为我的自定义类,以便循环遍历来自 csv 的行。

但是每次我得到 Empty 结果就像没有行一样。

我不确定我的方法有什么问题:

[HttpPost("import")]
public async Task<ActionResult> ImportData([FromForm] IFormFile file)
{

    using var memoryStream = new MemoryStream(new byte[file.Length]);
    await file.CopyToAsync(memoryStream);
    memoryStream.Position = 0;

    using (var reader = new StreamReader(memoryStream))
    using (var csvReader = new CsvReader(reader, System.Globalization.CultureInfo.InvariantCulture))
    {
        csvReader.Read();
        var records = csvReader.GetRecords<SiteDto>();
    }

    return Ok("ok");
}

这就是我的 CSV 的样子:

我的网站 Dto:

public class SiteDto
{
    public long Id { get; set; }
    public string Name { get; set; }
    public string Code { get; set; }
    public string CompanyName { get; set; }
    public string Location { get; set; }
}

当我扩展我的结果时,我看到了一些关于某些标题的警告?

【问题讨论】:

  • @maytham-ɯɐɥʇʎɐɯ 已经使用 try-catch 进行了尝试。这与标题有什么关系吗?请检查我的编辑
  • 您是否尝试过更改类属性名称或手动提供Name attributes 以匹配您的 csv 文件?
  • @maytham-ɯɐɥʇʎɐɯ using var 不是这样工作的——当它超出范围时会被处理掉。
  • @stuartd 肯定同意,这就是我在睡觉时评论迟到时会发生的情况????

标签: c# csv .net-core memorystream csvhelper


【解决方案1】:

https://joshclose.github.io/CsvHelper/getting-started

GetRecords 方法将返回一个 IEnumerable,该 IEnumerable 将产生 记录。这意味着只返回一条记录 迭代记录的时间。

尝试调用ToList() 来迭代记录并删除csvReader.Read();GetRecords() 在内部调用 Read()。同时使用会导致CsvReader 跳过标题行。

using (var reader = new StreamReader(memoryStream))
using (var csvReader = new CsvReader(reader, System.Globalization.CultureInfo.InvariantCulture))
{
    var records = csvReader.GetRecords<SiteDto>().ToList();
}

还要为您的类添加一个名称属性,以便CsvHelper 知道如何映射Id 属性。

public class SiteDto
{
    [Name("SiteId")]
    public long Id { get; set; }
    public string Name { get; set; }
    public string Code { get; set; }
    public string CompanyName { get; set; }
    public string Location { get; set; }
}

【讨论】:

    【解决方案2】:

    我已经创建了通用 csv 文件转换器到 T 类型列表

    public static class CSVParser
    {
        
       
        public static DataTable ConvertCSVtoDataTable(IFormFile file)
        {
            DataTable dt = new DataTable();
            using (var stream = file.OpenReadStream())
            using (StreamReader sr = new StreamReader(stream))
            {
                string[] headers = sr.ReadLine().Split(',');
                foreach (string header in headers)
                {
                    dt.Columns.Add(header);
                }
                while (!sr.EndOfStream)
                {
                    string[] rows = sr.ReadLine().Split(',');
                    DataRow dr = dt.NewRow();
                    for (int i = 0; i < headers.Length; i++)
                    {
                        dr[i] = rows[i];
                    }
                    dt.Rows.Add(dr);
                }
    
            }
    
    
            return dt;
        }
        public static List<T> ConvertDataTable<T>(DataTable dt)
        {
            List<T> data = new List<T>();
            foreach (DataRow row in dt.Rows)
            {
                T item = GetItem<T>(row);
                data.Add(item);
            }
            return data;
        }
        private static T GetItem<T>(DataRow dr)
        {
            Type temp = typeof(T);
            T obj = Activator.CreateInstance<T>();
    
            foreach (DataColumn column in dr.Table.Columns)
            {
                foreach (PropertyInfo pro in temp.GetProperties())
                {
                     
    
                if (pro.Name == column.ColumnName)
                    {
                        var typeGEt = pro.PropertyType;
                        Type type = Nullable.GetUnderlyingType(pro.PropertyType) ?? pro.PropertyType;
                        string typeName = type.Name;
    
                       try
                        {
                            if (typeName == "Int16" || typeName == "Int32" || typeName == "Int64")
                            {
                                pro.SetValue(obj, Convert.ToInt32(dr[column.ColumnName]), null);
    
                            }
                            else if (typeName == "DateTime")
                            {
    
                                pro.SetValue(obj, DateTime.ParseExact((string)dr[column.ColumnName], "mm/dd/yyyy", CultureInfo.InvariantCulture), null);
    
                            }
                            else
                            {
                                pro.SetValue(obj, dr[column.ColumnName], null);
    
                            }
                        }
    
                        catch(Exception ex)
                        {
                            continue;
    
                        }
    
    
    
                    }
                    else
                        continue;
                }
            }
            return obj;
        }
    
    
        public static IEnumerable<T> toList<T>(this DataTable? dt)
        {
            List<T> data = new List<T>();
            foreach (DataRow row in dt.Rows)
            {
                T item = GetItem<T>(row);
                data.Add(item);
            }
            return data;
        }
    
        public static string getExtension(this string name)
        {
           return Path.GetExtension(name);
            
        }
        public static IEnumerable<T> CSVToList<T>(this IFormFile? file)
        {
            if (file != null)
            {
                 if (file.FileName.getExtension() != ".csv")
                    throw new Exception("File is not valid CSV");
                else
                    return ConvertCSVtoDataTable(file).toList<T>();
    
            }
            else
                throw new Exception("File can not be empty");
        }
     }
    

    使用这个

    postedFile.CSVToList<TypeModal>();
    

    postedFile 是 IFormFile,TypeModal 是 Entity

    【讨论】:

    • 您好 Ahsan Ismail,虽然您的回答提供了一个可能的解决方案来读取 CSV 文件。我不确定它是否真的回答了关于如何使用 CsvHelper .NET 库读取 CSV 的原始问题。
    猜你喜欢
    • 1970-01-01
    • 2023-02-10
    • 1970-01-01
    • 1970-01-01
    • 2019-11-21
    • 1970-01-01
    • 2020-12-30
    • 2016-02-28
    • 2015-05-08
    相关资源
    最近更新 更多