2

I'm working on an MVC4 C# project in VS2010.

I would like to allow the user to upload the contents of a .csv file to a database but there is a requirement to first echo the contents of the file to screen (as a final visual check) before submitting. What would be the best approach of submitting to the database as I am struggling to find a way of persisting the complex object in the view?

Here is the view where I am using a form to allow the user to upload the csv file:

@model IEnumerable<MyNamespace.Models.MyModel>

@{
    ViewBag.Title = "Upload";
    WebGrid grid = new WebGrid(Model, rowsPerPage: 5);
}

<h2>Upload</h2>

<form action="" method="post" enctype="multipart/form-data">

  <label for="file">Filename:</label>
  <input type="file" name="file" id="file" />

  <input type="submit" />

</form>

<h2>Grid</h2>

@grid.GetHtml(

    //Displaying Grid here)

   <p>
    @Html.ActionLink("Submit", "Insert")
   </p>

Here is the action in the controller that processes the csv file:

[HttpPost]
        public ActionResult Upload(HttpPostedFileBase file)
        {

                var fileName = Path.GetFileName(file.FileName);
                var path = Path.Combine(Server.MapPath("~/App_Data"), fileName);
                file.SaveAs(path);

                //Stream reader will read test.csv file in current folder
                StreamReader sr = new StreamReader(path);
                //Csv reader reads the stream
                CsvReader csvread = new CsvReader(sr);


                List<MyModel> listMyModele = new List<MyModel>();  // creating list of model.
                csvread.Configuration.RegisterClassMap<MyModelMap>();         // use mapping specified.
                listMyModel = csvread.GetRecords<MyModel>().ToList();

                sr.Close();  

            //return View();
            return View(listMyModel);
        }

Up until this point everything is simple, I can upload the csv to the controller, read using CsvHelper, produce a list of MyModel objects and display in the view within a grid. To reiterate my initial question, is it now possible to submit the complex object (the list of MyModel) from the view as I can't figure out a way of making it available to an action within the controller.

Thank you.

RicHard
  • 21
  • 2

1 Answers1

0

Yes it's possible, It's "easier" if you have a Model with the IEnumerable in it so you can use the naming convention like this:

Property[index].ItemProperty

for every Html input/select field.

If you want to keep the IEnumerable as Model I think the naming convention is something like this:

ItemProperty[index]

So translated in code:

@Html.TextBoxFor(t => t.Property, new { name = "Property[" + i + "]" })

where i comes from a for loop to render all items or something like that.

I have already done it but I can't find the code at the moment. KendoUI uses this scheme for its multirows edit in the grid component.

You can check their POST AJAX requests for the right naming convention.

EDIT 1:

Otherwise you can think about store the model somewhere temporarily and retrieve it every time and updating with user inputs. It's a little more expensive but probably easier to write. Something like an updated csv file or a temporary db table.

Matteo Bruni
  • 243
  • 4
  • 12
  • Thanks for the suggestions @MatteoBruni, you got me thinking with the idea to temporarily store the object and retrieve later. So I looked into possibilites of re-reading the CSV that gets saved to the filesystem or putting the object in the session. In the end, it was very simple to store/retrieve to/from the session as found in this link [how-to-use-sessions-in-an-asp-net-mvc-4-application](http://stackoverflow.com/questions/14138872/how-to-use-sessions-in-an-asp-net-mvc-4-application). – RicHard Jul 20 '16 at 18:33