-1

The way this is setup is, -There is a View which takes the CSV upload -There is a Controller Partial View Action which is supposed to retrieve the parse the CSv and read the objects from the CSV and pass that back to the PArtial View. -The Partial View is than SUPPOSED to render on the page with all the records.

But apparently the bulkClients object appears null.

Here is the Controller :-

public ActionResult UploadBulkClients()
    {
        return View();
    }

//    [HttpPost]
    public PartialViewResult _UploadBulkClients(HttpPostedFileBase bulkClients) 
    {
        if (bulkClients != null)
        {
            try
            {
                StreamReader reader = new StreamReader(bulkClients.InputStream);
                while (reader != null)
                {
                    var csv = new CsvReader(reader);
                    csv.Read();
                    csv.ReadHeader();

                    while (csv.Read())
                    {
                        newRecord.Add(new ClientAgencyViewModel()
                        {
                            Id = UrbanLighthouse.Shared.Statics.NewUniqueGUID(),
                            ReferenceNo = csv["ReferenceNo"].ToString(),
                            FirstName = csv["FirstName"].ToString(),
                            MiddleName = csv["MiddleName"].ToString(),
                            LastName = csv["LastName"].ToString(),
                            StreetAddress = csv["StreetAddress"].ToString(),
                            City = csv["City"].ToString(),
                            PostalCode = csv["PostalCode"].ToString(),
                            Province = Guid.Parse(csv["Province"].ToString()),
                            Phone = csv["Phone"].ToString(),
                            Email = csv["Email"].ToString()
                        });
                    }
                    foreach (var item in newRecord)
                    {
                        if (repository.DoesEmailExist(item.Email) == true)
                        {
                            item.Email = item.Email + " : " + "Invalid Email Address";
                        }
                        else
                        {
                            item.Email = item.Email + " : " + "This Email is Good";
                        }
                    }
                }
                return PartialView(newRecord);
            }
            catch (System.IO.IOException e)
            {
                return PartialView(e);
            }
        }
        else
        {
            newRecord.Add(new ClientAgencyViewModel()
            {
                ReferenceNo = "Empty",
                FirstName = "Empty",
                MiddleName = "Empty",
                LastName = "Empty",
                StreetAddress = "Empty",
                City = "Empty",
                PostalCode = "Empty",
                Province = Guid.Empty,
                Phone = "Empty",
                Email = "Empty"
            });
            return PartialView(newRecord);
        }
    }

Here is how the View is layed out :- @model string @{ Layout = "~/Views/Shared/_LayoutAnonymous.cshtml"; AjaxOptions options = new AjaxOptions { UpdateTargetId = "uploadList", InsertionMode = InsertionMode.Replace, HttpMethod = "POST" }; }

            <div>
                @using (Ajax.BeginForm("_UploadBulkClients", "Client",options, new { enctype = "multipart/form-data" , role = "form", @class = Css.Form, @id = "formLogin" , action = "/Client/_UploadBulkClients" }))
                {
                <div class="@Css.FormGroup">
                    <h1>Client Bulk Upload</h1>

                    <div class="@Css.InputGroup">
                        <label>Upload CSV File</label>
                        <input type="file" name="postedFile" />
                    </div>

                    <div class="@Css.InputGroup">
                        @Html.Submit("Submit")
                    </div>

                </div>
                }
            </div>

            <div>
                <table class="table table-bordered table-striped">
                    <thead>
                        <tr>
                            <th>Reference No</th>
                            <th>FirstName</th>
                            <th>MiddleName</th>
                            <th>LastName</th>
                            <th>Phone</th>
                            <th>Email</th>
                            <th>StreetAddress</th>
                            <th>City</th>
                            <th>PostalCode</th>
                            <th>Province</th>
                        </tr>
                    </thead>
                    <tbody id="uploadList">
                        @Html.Action("_UploadBulkClients","")
                    </tbody>
                </table>

            </div>

When the HttpPost decorator is left on top of the PartialView Method, it gives an Error in the View @Html.Action("_UploadBulkClients","") saying that the _UploadBulkClients Action method does not exist.

EDIT:- It seems that the upload is not posting the csv file, and I would not understand why that would be, as the Ajax form seems to be the way it is supposed to be.

Any help would be appreciated !

Umar Aftab
  • 527
  • 4
  • 24
  • You cannot upload a file using `Ajax.BeginForm()`. Use `FormData` - refer [this answer](http://stackoverflow.com/questions/29293637/how-to-append-whole-set-of-model-to-formdata-and-obtain-it-in-mvc/29293681#29293681) –  Feb 16 '18 at 20:47
  • @StephenMuecke I am little confused, I am not sure how to use FormData, and what do you mean by `you can serialize the model to FormData using` – Umar Aftab Feb 16 '18 at 21:34
  • `var formdata = new FormData($('form').get(0));` – Umar Aftab Feb 16 '18 at 21:35
  • Just use the code in the link I gave you :) But your file input is named `postedFile` which means the parameter in your POST method needs to match - i.e. `HttpPostedFileBase postedFile` –  Feb 16 '18 at 21:44
  • If I understood javascript, I wouldn't ask, I would need you to explain to me how to use FormData, or give me a link, because I am still new to ASP.NET MVC and still learning. JavaScript is still something I need to sit and learn, how to use it ! – Umar Aftab Feb 16 '18 at 21:47
  • I have given you a link. It shows exactly how to do it. –  Feb 16 '18 at 21:47
  • I, will have to completely remove Ajax Options and use Html.BeginForm – Umar Aftab Feb 16 '18 at 21:50
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/165311/discussion-between-stephen-muecke-and-umar-aftab). –  Feb 16 '18 at 21:52

1 Answers1

0

With the help of Stephen, I was able to figure out the answer, it had to be done using JavaScript and not AjaxOptions in C#.

Here are the steps just in case someone encounters something similar :- 1. The Controller Method which returns the form

    public ActionResult UploadBulkClients()
    {
        return View();
    }

2. The form has to be a simple form and not an Ajax form. I used Html Helpers here:

@using (Html.BeginForm("_UploadBulkClients", "Client",null, FormMethod.Post , new { enctype = "multipart/form-data" , role = "form", @class = Css.Form, @id = "uploadForm" }))
{
<div class="@Css.FormGroup">
    <h1>Client Bulk Upload</h1>

    <div class="@Css.InputGroup">
        @Html.LabelFor(m=>m.File)
        @Html.TextBoxFor(m=>m.File, new { type= "file"})
    </div>

    <div class="@Css.InputGroup">
        @Html.Submit("Submit")
    </div>

</div>
}

3. The next part is the controller method which return the partial view.

    [HttpPost]
    public PartialViewResult _UploadBulkClients(HttpPostedFileBase file) 
    {
        if (file != null)
        {
            try
            {
                using (var reader = new StreamReader(file.InputStream))
                using (var csv = new CsvReader(reader))
                {
                    csv.Read();
                    csv.ReadHeader();
                    while (csv.Read())
                    {                        
                        newRecord.Add(new ClientAgencyViewModel()
                        {
                               Id = UrbanLighthouse.Shared.Statics.NewUniqueGUID(),
                               ReferenceNo = csv["ReferenceNo"],
                               FirstName = csv["FirstName"].ToString(),
                               MiddleName = csv["MiddleName"].ToString(),
                               LastName = csv["LastName"].ToString(),
                               StreetAddress = csv["StreetAddress"].ToString(),
                               City = csv["City"].ToString(),
                               PostalCode = csv["PostalCode"].ToString(),
                               ProvinceText = csv["Province"].ToString(),
                               Phone = csv["Phone"].ToString(),
                               Email = csv["Email"].ToString()
                        });
                    }
                    foreach (var item in newRecord)
                    {
                        if (repository.DoesEmailExist(item.Email) == true)
                        {
                            item.Email = item.Email + " : " + "Email Address Already Exists";
                        }
                        else
                        {
                            item.Email = item.Email + " : " + "This Email is Good";
                        }
                    }
                }
                return PartialView(newRecord);
            }
            catch (System.IO.IOException e)
            {
                return PartialView(e);
            }
        }
        else
        {
            newRecord.Add(new ClientAgencyViewModel()
            {
                ReferenceNo = "Empty",
                FirstName = "Empty",
                MiddleName = "Empty",
                LastName = "Empty",
                StreetAddress = "Empty",
                City = "Empty",
                PostalCode = "Empty",
                ProvinceText = "Empty",
                Phone = "Empty",
                Email = "Empty"
            });
            return PartialView(newRecord);
        }
    }

4. The next part is the partial View which renders the output from the controller method.

  @model List<WebPlatform.ViewModels.ClientAgencyViewModel>
  @foreach (var item in Model)
  {
<tr>
    <td>@item.ReferenceNo</td>
    <td>@item.FirstName</td>
    <td>@item.MiddleName</td>
    <td>@item.LastName</td>
    <td>@item.Phone</td>
    <td>@item.Email</td>
    <td>@item.StreetAddress</td>
    <td>@item.City</td>
    <td>@item.PostalCode</td>
    <td>@item.ProvinceText</td>
</tr>
   }

5. And last but not the least the Ajax functionality written within the JavaScript because AjaxOptions will not work in this particular situation.

$('#uploadForm').submit(function(e) {
e.preventDefault();
var formdata = new FormData($(this).get(0));
$.ajax({
    url: '@Url.Action("_UploadBulkClients","Client")',
    type: 'POST',
    data: formdata,
    processData: false,
    contentType: false,
    success: function (response) {
        $('#uploadList').html(response);
     }
   },

  );
});
Umar Aftab
  • 527
  • 4
  • 24