0

I've created a CSV parser using the most recommended nuget I could find on here, CSVReader. I think my code is almost there its just posting the file to the controller actionmethod I can't quite find enough on. I get the error:

System.IO.FileNotFoundException: 'Could not find file 'C:\Program Files (x86)\IIS Express\System.Web.HttpPostedFileWrapper'.'

Controller action method:

    [HttpPost]
    public ActionResult CreateBulk(HttpPostedFileBase attachmentcsv)
    {
        if (ModelState.IsValid)
        {
            using (CsvReader csv = new CsvReader(new StreamReader(attachmentcsv.ToString()), true))
            {
                csv.Configuration.HasHeaderRecord = true;
                var records = csv.GetRecords<Client>().ToList();

                foreach (var item in records)
                {
                    String Strip = item.homePage.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 userId = User.Identity.GetUserId();
                    var UserTableID = db.UserTables.Where(c => c.ApplicationUserId == userId).First().ID;
                    var newclient = new Client { clientN = item.clientN, homePage = Metric[0], clientEmail = item.clientEmail, contName = item.contName.First().ToString().ToUpper() + item.contName.Substring(1), monthlyQuota = item.monthlyQuota, TrustFlow = Int32.Parse(Metric[1]), CitationFlow = Int32.Parse(Metric[2]), RI = Int32.Parse(Metric[3]), MJTopicsID = item.MJTopicsID, UserTableID = UserTableID };
                    ViewBag.newdomain = newclient;
                    db.Clients.Add(newclient);
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
            }
        }
        return RedirectToAction("Index");

View upload button:

@using (Html.BeginForm("CreateBulk", "Clients", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="form-group">
<label for="attachment">Select a Csv File</label>
<label class="btn btn-default btn-file">
<input type="file" name="attachmentcsv" id="attachmentcsv" hidden>
</label>
</div>
<button type="submit" class="btn btn-primary">Upload</button>
}

Client Model:

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace Linkofy.Models
{
public class Client
{
    public int ID { get; set; }

    [Required]
    [Display(Name = "Client")]
    public string clientN { get; set; }

    [Display(Name = "Website")]
    public string homePage{ get; set; }

    [EmailAddress]
    [Display(Name = "Contact Email")]
    public string clientEmail { get; set; }

    [Display(Name = "Contact Name")]
    public string contName { get; set; }

    [Display(Name = "Monthly")]
    public int monthlyQuota { get; set; }

    [Display(Name = "TF")]
    public int TrustFlow { get; set; }

    [Display(Name = "CF")]
    public int CitationFlow { get; set; }

    [Display(Name = "RIPs")]
    public int RI { get; set; }

    public int? MJTopicsID { get; set; }
    public virtual MJTopics MJTopics { get; set; }

    public int UserTableID { get; set; }
    public virtual UserTable UserTable { get; set; }

    public virtual ICollection<Link> Links { get; set; }
    public virtual ICollection<Status> Statuss { get; set; }
}
}
Lucie
  • 131
  • 1
  • 9

1 Answers1

1

You should check out: File upload in MVC

But looking into your code there are a few things that I wanted to point out:

Isolating the attachmentcsv.ToString() line it appears that this returns the type of System.Web.HttpPostedFileWrapper, this is why this string is being appended onto the file location.

I believe you may be looking for the attachmentcsv.FileName, which according to documentation of the type (https://msdn.microsoft.com/en-us/library/system.web.httppostedfilewrapper(v=vs.110).aspx)

Gets the fully qualified name of the file on the client

I'm not sure if you are using the framework or the core version of ASP, but I believe in the framework version of ASP the "correct" way of accessing upload files (as indicated in the linked answer) is to go through the Request object: Request.Files.

https://msdn.microsoft.com/en-us/library/system.web.httprequest.files(v=vs.110).aspx

In the core version of ASP you can have a IFileForm as indicated here:

https://learn.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads

[HttpPost("UploadFiles")]
public async Task<IActionResult> Post(List<IFormFile> files)
{
    long size = files.Sum(f => f.Length);

    // full path to file in temp location
    var filePath = Path.GetTempFileName();

    foreach (var formFile in files)
    {
        if (formFile.Length > 0)
        {
            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                await formFile.CopyToAsync(stream);
            }
        }
    }

    // process uploaded files
    // Don't rely on or trust the FileName property without validation.

    return Ok(new { count = files.Count, size, filePath});
}

Hope this helps

Mark Davies
  • 1,447
  • 1
  • 15
  • 30
  • Wow what a well written answer! Thank you. So If I create a model binding of iformfile mimicking the client model with the extra few lines will it then work the way I intend it to. Through var records = csv.GetRecords().ToList(); with the iform file binding it to the model originally so I can save it to the database? – Lucie Jan 20 '18 at 17:43
  • also I'm using MVC5 – Lucie Jan 20 '18 at 17:48
  • In MVC5 something like this should work in being able to import your file (https://gist.github.com/joro550/544ba7b4a99b0285ac365328b786fff7) – Mark Davies Jan 20 '18 at 17:54
  • seems to be able to read the file! Great thanks, just one last quick question its stuck on the Id column saying its not found in the file how would I get it to ignore that? – Lucie Jan 20 '18 at 18:13
  • I'm assuming you mean in the library? I have to admit I'm not too familier with the library that you are using, but have found an issue that looks similar to the one your having (https://github.com/JoshClose/CsvHelper/issues/339), the owner has a suggestion to set `csv.Configuration.WillThrowOnMissingFields = false;` - if this does not work, may be worth throwing up another question – Mark Davies Jan 20 '18 at 18:25
  • 1
    it says the ireaderconfiguration does not contain a definition for willthrowonmissingfields, perhaps the library has been changed since, will look into it tomorrow more and if not post a question, thanks for your time! – Lucie Jan 20 '18 at 19:08