0

I am trying to upload a file using AJAX using C#-Razor. When I submit by clicking on the button the controller method is not being executed. How can I solve this ?

My code is as follows:

View

<div class="form-group">
    @Html.TextBoxFor(model => model.IMG, new { @class = "control-label col-md-12", type = "file", placeholder = "Industry", name = "files[]", id="FileUpload" })
    @Html.LabelFor(model => model.IMG, new { @class = "col-md-12 " })
    @Html.ValidationMessageFor(model => model.IMG)
</div>
<div class="form-group">
    <div class="col-md-offset-2 col-md-10">
        <input type="button" value="Create" class="btn btn-default" id="UseShipAddr" />
   </div>
</div>

AJAX

$('#UseShipAddr').click(function () {
        var formData = new FormData();
        var totalFiles = document.getElementById("FileUpload").files.length;
        for (var i = 0; i < totalFiles; i++) {
            var file = document.getElementById("FileUpload").files[i];

            formData.append("IMG", file);
            alert("h" + file);
        }
        formData.append("name", "James");
        formData.append("age", "1");

        $.ajax({
            url: "/Post/New",
            type: "POST",
            data: formData,
            cache: false,
            async: true,
            success: function (data) {
                alert(data);
            }
        });
    });

Controller

[HttpPost]
//[ValidateAntiForgeryToken]
public async Task<ActionResult> New([Bind(Include="age","name","IMG")] POST rec)
{
   if (ModelState.IsValid)
      {
         db.REC.Add(rec);
         await db.SaveChangesAsync();
         return RedirectToAction("My", "Post");
      }
   return View(rec);
}
Shahzad
  • 1,315
  • 2
  • 22
  • 42
Illep
  • 16,375
  • 46
  • 171
  • 302
  • 1
    Are you pointing to correct URI, `"/Post/New"` and method name ?`Create`? – Satpal Feb 12 '17 at 06:02
  • That was a typo. I corrected it now. The problem still exist. – Illep Feb 12 '17 at 06:33
  • Your not setting the correct ajax options, and you can simply use `var formdata = new FormData($('form').get(0));` to serialize everything - refer [this answer](http://stackoverflow.com/questions/29293637/how-to-append-whole-set-of-model-to-formdata-and-obtain-it-in-mvc/29293681#29293681) (and then `.append()` if you want to send additional data that is not in a form control –  Feb 12 '17 at 07:34
  • And as a side note new { `name = "files[]" }` does nothing at all fortunately. And why add `new { id="FileUpload" }` to override the default `id` attribute? - you can just use `$('#IMG'). And since its not `multiple = "multiple", there is only one file so the loop is not really necessaey. –  Feb 12 '17 at 07:37
  • You also have `return RedirectToAction("My", "Post");` in your controller method but are making a ajax call (ajax calls never redirect - the whole point of them is to stay on the same page. If your wanting to redirect, then DO NOT use ajax) –  Feb 12 '17 at 22:56

2 Answers2

0

Send the extra parameters in a querystring. Here is the AJAX code:

$.ajax({
    url: "/Post/New?name=James&age=1",
    type: "POST",
    data: formData,
    cache: false,
    async: true,
    contentType: false, // Not to set any content header  
    processData: false, // Not to process data  
    success: function (data) {
        alert(data);
    }
});

And your controller should be similar to below:

public async Task<ActionResult> New(string name, int age)
{
    try
    {
        foreach (string file in Request.Files)
        {
            var fileContent = Request.Files[file];
            if (fileContent != null && fileContent.ContentLength > 0)
            {
                // get a stream
                var stream = fileContent.InputStream;
                // and optionally write the file to disk
                var fileName = Path.GetFileName(file);
                using (var fileStream = new MemoryStream())
                {
                    stream.CopyTo(fileStream);
                }

                // File is in the memory stream, do whatever you need to do
            }
        }
    }
    catch (Exception)
    {

        // whatever you want to do
    }
}
CodingYoshi
  • 25,467
  • 4
  • 62
  • 64
  • Can you also show me the corresponding HTML part of your code ? – Illep Feb 12 '17 at 06:41
  • Same as yours. I only changed the portion in $.Ajax and controller code. – CodingYoshi Feb 12 '17 at 06:48
  • Thanks for the update. Let me try this out and get back to you. – Illep Feb 12 '17 at 06:59
  • It still doesn't work. THe controller doesn't get fired. – Illep Feb 12 '17 at 11:49
  • Please open the chrome, or any browser's, debugger and select the Network tab. Then see what url is being called and what the response is. – CodingYoshi Feb 12 '17 at 15:09
  • Without embedding the parameters in the query string (url). Can I append it to `formData` ? If so how can I do it, and retrieve it from the Controller ? – Illep Feb 12 '17 at 16:13
  • It shows the URL which I intend to pass. Nothing apart from that. – Illep Feb 12 '17 at 16:26
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/135509/discussion-between-codingyoshi-and-illep). – CodingYoshi Feb 12 '17 at 16:36
  • OP is already appending the values to the `FormData` object so adding the parameters in the query string is pointless. And using `string` parameters and `Request.Files` instead of binding to the model as OP is doing is terrible advice. –  Feb 12 '17 at 22:54
0

You are not specifying any form while creating the form in object in your form submit #UseShipAddr click event. please specify your form while creating object as:

var formData = new FormData($(#formID)[0]);

or create form constructor

var dataString = new FormData();

append file to the form

dataString.append("UploadedFile", selectedFile);
var form = $('#formID')[0];
var dataString = new FormData(form);

now send that string to the action in controller.

There are lots of problem in your request. First remove this then you'll be able to call that action of the controller.

Shahzad
  • 1,315
  • 2
  • 22
  • 42
  • What do you mean ? Can you show me via a code if possible. Sorry I am a newbie. – Illep Feb 12 '17 at 11:03
  • No this is not correct. That is not how `FormData` works. – CodingYoshi Feb 12 '17 at 15:07
  • I am using it to upload file with some parameters in ajax call. What I know when i pass complete object of form data to the action using ajax call, on the action I need to name parameters with the same name as in the form field names. – Shahzad Feb 12 '17 at 15:42
  • @CodingYoshi try to read [this article](https://www.codeproject.com/Articles/1021004/Upload-File-Using-Ajax-And-HTML-in-MVC) on code project. you'll understand my point. – Shahzad Feb 12 '17 at 15:54
  • @Illep as you are newbie you can also try same article it will help you alot. – Shahzad Feb 12 '17 at 15:54
  • Did you read this part: `//we can create form by passing the form to Constructor of formData object //or creating it manually using append function //but please note file name should be same like the action Parameter //var dataString = new FormData(); //dataString.append("UploadedFile", selectedFile);` – CodingYoshi Feb 12 '17 at 16:17