【问题标题】:Why does it only display one line? ie Why is it only reading the first line of the textfile?为什么只显示一行?即为什么它只读取文本文件的第一行?
【发布时间】:2019-08-06 17:31:40
【问题描述】:

我正在尝试从每行数据以逗号分隔的文本文件中读取(提供的文本文件)。 读完这一行后,我将数据分开,最后以列表的形式发送到我的视图中。

问题是它只读取/显示第一行。

文本文件:

John,Smith,02-05-1969,0001,700000,Manager,None  
Jane,Doe,04-01-1977,0002,600000,Employee,John  
Jim,Bean,11-09-1985,0003,650000,Employee,Jane  
Roger,Wilco,19-12-1990,0004,200000,Trainee,Jane  
Susan,Roe,22-06-1995,0005,180000,Trainee,Jane

控制器:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using EpiUseTechAssessment.ViewModels;
    using System.IO;

    namespace EpiUseTechAssessment.Controllers
    {
        public class HRManagerController : Controller
        {
    // GET: HRManager
            public ActionResult HRManager()
            {
                List<EmployeeViewModel> employees= GetTestData();
                return View(employees);
            }

                private List<EmployeeViewModel> GetTestData()
            {

                string[] Lines;
                string filepath = @"D:Employees.txt";
                StreamReader file = new StreamReader(filepath);
                string Name;
                string Surname;
                string Birthdate;
                int EmpNum;
                int Salary;
                string Role;
                string Reports;
                List<EmployeeViewModel> employees = new      List<EmployeeViewModel>();

                while (file.EndOfStream == false)
                {
                    //Read textfile
                    Lines = System.IO.File.ReadAllLines(filepath);

                    //Seperate data and assign
                    foreach (string line in Lines)
                    {
                        string[] L = line.Split(',');
                        Name = L[0];
                        Surname = L[1];
                        Birthdate = L[2];
                        EmpNum = Convert.ToInt32(L[3]);
                        Salary = Convert.ToInt32(L[4]);
                        Role = L[5];
                        Reports = L[6];

                    //Send to ViewModel
                    EmployeeViewModel emp = new EmployeeViewModel(Name,         Surname, Birthdate, EmpNum, Salary, Role, Reports);
                    employees.Add(emp);
                    return employees;
                    }

                }
                file.Close();
                return (employees);

            }

查看:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;

    namespace EpiUseTechAssessment.ViewModels
    {
        public class EmployeeViewModel
        {
            public string _Name { get; set; }
            public string _Surname { get; set; }
            public string _Birthdate { get; set; }
            public int _EmpNum { get; set; }
            public int _Salary { get; set; }
            public string _Role { get; set; }
            public string _Reports { get; set; }

            public EmployeeViewModel(string name, string surname, string         birthdate, int empnum, int salary, string role, string reports)
            {
                _Name = name;
                _Surname = surname;
                _Birthdate = birthdate;
                _EmpNum = empnum;
                _Salary = salary;
                _Role = role;
                _Reports = reports;
            }
        }
    }

类:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;

    namespace EpiUseTechAssessment.ViewModels
    {
        public class EmployeeViewModel
        {
            public string _Name { get; set; }
            public string _Surname { get; set; }
            public string _Birthdate { get; set; }
            public int _EmpNum { get; set; }
            public int _Salary { get; set; }
            public string _Role { get; set; }
            public string _Reports { get; set; }

            public EmployeeViewModel(string name, string surname, string birthdate, int empnum, int salary, string role, string reports)
            {
                _Name = name;
                _Surname = surname;
                _Birthdate = birthdate;
                _EmpNum = empnum;
                _Salary = salary;
                _Role = role;
                _Reports = reports;
            }
        }
    }

【问题讨论】:

  • 为什么在 While 循环中调用 return employees;
  • 有一些库可以为您读取、解析和键入 CSV 文件,它们会更好更快地工作。否则,这似乎不太minimal reproducible example
  • @RahulSingh 所说的——您在for...eachwhile 中都返回了结果。您想在 完全构建完成之后(即在这两个循环之外)返回它
  • 谢谢,我已经删除了Return employees,并且只将它放在循环之外。现在我的视图根本不会加载? @RahulSingh 和 @Jonathan
  • 您打开一个 StreamReader(命名文件),然后通过路径直接从文件中读取(忽略该阅读器)。所以删除 StreamReader 和“while”

标签: c# asp.net-mvc linq


【解决方案1】:

您当前正在从循环内返回一个结果。这将在第一次迭代后终止循环。

试试下面,我已经将csv记录的解析分离为一个函数。关键点是使用 using statement 作为 StreamReader 并在循环外返回结果。 using 语句将确保流在不再需要时被正确处理。您应该为文件不存在或无法读取等情况添加额外的错误处理。

private List<EmployeeViewModel> GetTestData(string filePath)
{
    List<EmployeeViewModel> employees = new List<EmployeeViewModel>();

    using (StreamReader file = new StreamReader(filepath))
    {
        // Read all records from the textfile
        string[] Lines = System.IO.File.ReadAllLines(filepath);

        //Separate data and assign
        foreach (string line in Lines)
        {
            employees.Add(ParseAsEmployeeModel(line));
        }
    }

    // Will return an empty array when no records are available
    // Depending on use case a null may be preferable
    return employees;
}

private EmployeeViewModel ParseAsEmployeeModel(string csvRecord)
{
    string[] L = line.Split(',');
    string Name = L[0];
    string Surname = L[1];
    DateTime Birthdate = DateTime.Parse(L[2]); // TODO : error checking to ensure date is valid
    int EmpNum = Convert.ToInt32(L[3]); // TODO: You are losing leading zeros - is this correct?
    int Salary = Convert.ToInt32(L[4]);
    string Role = L[5];
    string Reports = L[6];

    return new EmployeeViewModel(Name, Surname, Birthdate, EmpNum, Salary, Role, Reports);
}

除了上述之外,我建议将生日存储为 DateTime 而不是字符串,如下所示。

public class EmployeeViewModel
{
    public string _Name { get; set; }
    public string _Surname { get; set; }
    public DateTime _Birthdate { get; set; }
    public int _EmpNum { get; set; }
    public int _Salary { get; set; }
    public string _Role { get; set; }
    public string _Reports { get; set; }

    public EmployeeViewModel(string name, string surname, DateTime birthdate, int empnum, int salary, string role, string reports)
    {
        _Name = name;
        _Surname = surname;
        _Birthdate = birthdate;
        _EmpNum = empnum;
        _Salary = salary;
        _Role = role;
        _Reports = reports;
    }
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多