1

So I've been trying for the past week to build a CSV parser, I tried Oledb reader but it seemed I had to have a connection string which linked to a certain folder whereas I want a dynamic location. I've now built this which seems like its almost there though on the 4th line:

StreamReader reader = new StreamReader(File.OpenRead(attachmentcsv));

File is underlined saying

Controller.File(byte[].string) is a method, which is not valid in the current context

I assume this means I need to put it in a function, though its the only place I will use it and don't really want to as I struggle with functions is there any alternative?

    [HttpPost]
    public ActionResult CreateBulk(HttpPostedFileBase attachmentcsv)
    {
        StreamReader reader = new StreamReader(File.OpenRead(attachmentcsv));
        List<string> clientN = new List<String>();
        List<string> homePage = new List<String>();
        List<string> clientEmail = new List<String>();
        List<string> contName = new List<String>();
        List<string> monthlyQuota = new List<String>();
        List<string> MJTopicsID = new List<String>();
        //string vara1, vara2, vara3, vara4;
        while (!reader.EndOfStream)
        {
            string line = reader.ReadLine();
            if (!String.IsNullOrWhiteSpace(line))
            {
                string[] values = line.Split(',');
                if (values.Length >= 4)
                {
                    clientN.Add(values[0]);
                    homePage.Add(values[1]);
                    clientEmail.Add(values[2]);
                    contName.Add(values[3]);
                    monthlyQuota.Add(values[4]);
                    MJTopicsID.Add(values[5]);
                }
            }
        }
        string[] AddclientN = clientN.ToArray();
        string[] AddhomePage = homePage.ToArray();
        string[] AddclientEmail = clientEmail.ToArray();
        string[] AddcontName = contName.ToArray();
        string[] AddmonthlyQuota = contName.ToArray();
        string[] AddMJTopicsID = contName.ToArray();

        var userId = User.Identity.GetUserId();
        var UserTableID = db.UserTables.Where(c => c.ApplicationUserId == userId).First().ID;

        for (int i = 0; i < AddclientN.Length; i++)
        {
            String Strip = AddhomePage[i].Replace("https://www.", "").Replace("http://www.", "").Replace("https://", "").Replace("http://", "").Replace("www.", "");
            string[] URLtests = { "https://www." + Strip, "http://www." + Strip, "https://" + Strip, "http://" + Strip };
            string[] Metric = MajesticFunctions.MajesticChecker(URLtests);
            var newclient = new Client { clientN = AddclientN[i], homePage = Metric[0], clientEmail = AddclientEmail[i], contName = AddcontName[i].First().ToString().ToUpper() + AddcontName[i].Substring(1), monthlyQuota = Int32.Parse(AddmonthlyQuota[i]), TrustFlow = Int32.Parse(Metric[1]), CitationFlow = Int32.Parse(Metric[2]), RI = Int32.Parse(Metric[3]), MJTopicsID = Int32.Parse(AddMJTopicsID[i]), UserTableID = UserTableID };
            ViewBag.newdomain = newclient;
            db.Clients.Add(newclient);
            db.SaveChanges();
        }
        return RedirectToAction("Index");
    }
liamcook
  • 143
  • 2
  • 10
  • 1
    To answer the question, there is a [`File`](https://msdn.microsoft.com/en-us/library/system.web.mvc.controller.file(v=vs.118).aspx) method on `Controller` that the compiler is trying to bind instead of the `File` class. Try changing it to `StreamReader reader = new StreamReader(System.IO.File.OpenRead(attachmentcsv));` – D Stanley Jan 17 '18 at 22:35
  • There are a few csv readers already in .Net, and some better ones already on NuGet. Are you doing this for the fun of it, or would you prefer to use an existing option? It's worth specifically noting the basic Split() method makes for a truly **awful** csv reader. Performance is poor and there are a great many edge cases that can cause it to create bad data for you. – Joel Coehoorn Jan 17 '18 at 22:39
  • @DStanley Thanks! Fixed the issue though it seems it needs a connection string as well, thanks though will look to the existing readers – liamcook Jan 17 '18 at 22:44
  • @JoelCoehoorn wasn't so much for fun haha just being quite a novice this way seemed simple though just doesn't work. I will look into the csv reader posted as an answer thanks. – liamcook Jan 17 '18 at 22:45
  • For future question please ask one thing at a time - either "how to parse CSV - here is my code" (I closed this one as duplicate of canonical answer for that) or "I'm getting this error when trying to write code" (which would be fine by itself, but you need [MCVE] instead of code posted currently). – Alexei Levenkov Jan 17 '18 at 22:49

1 Answers1

6

You shouldn't reinvent the wheel. You can try the CSVHelper library https://joshclose.github.io/CsvHelper/

One line of code to achieve what you are trying in many lines:

var records = csv.GetRecords<dynamic>();

You can find documentation here.

hbulens
  • 1,872
  • 3
  • 24
  • 45
Quentin Roger
  • 6,410
  • 2
  • 23
  • 36
  • Thanks will look into it! I did see this before, though as a novice the one I found using oledb offered the view functionality for the button and it was all connected but it seems this is far better – liamcook Jan 17 '18 at 22:49
  • This is the answer - don't. I've spent years working with CSV files and they might appear simple enough but there are an alarming number of variations out in the wilds, not to mention encodings etc ... use a library. – Jammer Jan 17 '18 at 22:51
  • @Jammer Yeah I see :/ probably best if I want to deploy it at some point anyways, thanks! – liamcook Jan 17 '18 at 22:57
  • how would I go about passing the csv from the view to the method though? I used httppostedfile before – liamcook Jan 18 '18 at 22:31