Raman Sinclair
Raman Sinclair

Reputation: 1283

File-upload saves empty file

I am writing file uploading module in c# using ajax&jQuery on ASP.NET MVC 5

I tried msdn example for backend code

    [HttpPost]
    public ActionResult Upload()
    {
        if (Request.Files.Count != 0)
        {
            for (int i = 0; i < Request.Files.Count; i++)
            {
                var file = Request.Files[i];
                var fileName = Path.GetFileName(file.FileName);
                var path = Path.Combine(Server.MapPath("~/Junk/"), fileName);
                file.SaveAs(path);
            }
        }

        return new EmptyResult();
    }

The problem is that this method creates empty file (size 0 bytes). I guess this happens because we don't read input stream, we're only reading filename on the example.

How to make this work?

Update 1 (posted js code):

<script type="text/javascript">
    $(document).ready(function () {
        $("#Upload").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("FileUpload", file);
            }
            $.ajax({
                type: "POST",
                url: '/Home/Upload',
                data: formData,
                dataType: 'json',
                contentType: false,
                processData: false,
                //beforeSend: beforeSendHandler,
                success: function(){
                    alert("CAT");
                },
                //error: errorHandler,
                // Form data
                data: formData,
                //Options to tell jQuery not to process data or worry about content-type.
                cache: false,
                contentType: false,
                processData: false
            });
            ajaxRequest.done(function () {
                alert("CAAT");
            });
        });
    });

</script>

Update 2 (added html-markup):

<div class="container body-content">
        <hr />
        <input type="file" id="FileUpload" multiple />
        <input type="button" id="Upload" value="Upload" />
        <hr />
        <footer>
       ...
        </footer>
    </div>

Upvotes: 1

Views: 3865

Answers (3)

Geoff James
Geoff James

Reputation: 3180

You're nearly there with your current code.

I've read about this one on: https://cmatskas.com/upload-files-in-asp-net-mvc-with-javascript-and-c/ and adapted my answer.

Try this:

Your upload section:

// The same as you already have,  but your button as a "button"
<div ...>

    <input type="file" id="FileUpload" multiple />
    <button type="button" id="Upload" value="Upload" />
    ...
</div>

Your jQuery:

<script type="text/javascript">
    $(document).ready(function () {
        $("#Upload").click(function () {
            var files = $("FileUpload").target.files;
            if (files.Length > 0)
            {
                // Check if the browser supports FormData
                if (window.FormData !== undefined) {
                    var formData = new FormData();
                    // Add the files 
                    for (var x = 0; x < files.length; x++){
                        data.append("file" + x, files[x]);
                    }

                    $.ajax({
                        type: "POST",
                        url: 'Home/Upload?id=someId'
                        data: formData,
                        dataType: 'json',
                        contentType: false,
                        processData: false,
                        //beforeSend: beforeSendHandler,
                        success: function(){
                            alert("CAT");
                        },
                        //error: errorHandler,
                        // Form data
                        data: formData,
                        //Options to tell jQuery not to process data or worry about content-type.
                        cache: false,
                        contentType: false,
                        processData: false
                    });
                    ajaxRequest.done(function () {
                        alert("CAAT");
                    });
                }
                else {
                    // If the browser does not support FormData, show an alert
                    alert("Your browser does not support this type of upload");
                }
            }); 
        }
    });
</script>

Your controller:

[HttpPost]
public ActionResult Upload(string id)
{
    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 write the file to disk
               var fileName = Path.GetFileName(file); 
               var path = Path.Combine(Server.MapPath("~/Junk"), fileName); 
               using (var fileStream = File.Create(path))
               {
                   stream.CopyTo(fileStream);
               }
           }
        }
    }
    catch (Exception)
    {
        Response.StatusCode = (int)HttpStatusCode.BadRequest;
        return Json("Upload failed");
    }

    return Json("Upload succeeded");
}

Please note you might want to change a couple of things around, but this should be pretty much what you need.

Hope this helps!

Upvotes: 1

mmushtaq
mmushtaq

Reputation: 3520

Possible way to do this:

 <form id="form1">
      <input accept="image/*" type="file" id="txtFileInpu" />
      <input type="submit" value="Upload" />
      </form>

JS

 <script type="text/javascript">
        var form = document.getElementById('form1').onsubmit = function (e) {
            e.preventDefault();

            var formdata = new FormData(); 
            var fileInput = document.getElementById('txtFileInput');
            if (fileInput != "" && fileInput.files.length > 0) {
                for (i = 0; i < fileInput.files.length; i++) {
                    formdata.append(fileInput.files[i].name, fileInput.files[i]);
                }
                var xhr = new XMLHttpRequest();
                xhr.open('POST', '/Controller/Upload');
                xhr.send(formdata);
                xhr.onreadystatechange = function () {
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        var result = xhr.responseText;
                        if(result=="Uploaded")
                              //file uploaded
                         else
                             //file not uploaded
                    }
                }
                return false;
            }
        }

    </script>

C#

public string Upload()
    {
        try
        {
             for (int i = 0; i < Request.Files.Count; i++)
            {
                HttpPostedFileBase file = Request.Files[i];

                string strTargetFolder = Server.MapPath("~/Junk");

                if (!Directory.Exists(strTargetFolder))
                {
                    Directory.CreateDirectory(strTargetFolder);
                }

                string targetPath = Path.Combine(strTargetFolder, file.FileName);
                file.SaveAs(targetPath);

            }
            return "Uploaded";
        }
        catch (Exception exp)
        {
            return "ERROR";
        }


}

Upvotes: 0

Rosan Shrestha
Rosan Shrestha

Reputation: 32

[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
var Image = Path.GetFileName(file.FileName);
string path = Path.Combine(Server.MapPath("~/images/Attachment"), Image);
file.SaveAs(path);
}

and in View section

@using (Html.BeginForm("Upload", "ControllerName", FormMethod.Post, new { enctype = "multipart/form-data" }))
{

<input type="file" name="file"/>
<button type="submit" Submit</button>
}

I hope this helps

Upvotes: 0

Related Questions