views:

37

answers:

2

I found this ajax file upload script here http://www.phpletter.com/Demo/AjaxFileUpload-Demo/

Which is supposed to add ajax functionality to my file upload form

<div id="dialog" title="Upload Image">
           <%
            Html.BeginForm("Upload", "BugTracker", FormMethod.Post,new { id="uploadForm",  enctype = "multipart/form-data"});
           %>

                Select a file: <input type="file" name="file" id="file" />   
                <h6>Upload a screenshot related to the ticket</h6>
                <input type="submit" class="button" value="Upload" id="upload" onclick="uploadImage();" name="submit" />


            <%Html.EndForm();%>
</div>

And I have set up a function to be called when my upload form is submitted like so:

function uploadImage() {

                    var action = $("#uploadForm").attr('action');

                    $.ajaxFileUpload(
                    { url: action,
                        secureuri: false,
                        fileElementId: 'file',
                        dataType: 'json',
                        success: function (data, status) {
                            $("#RelatedFileName").val() = data.FileName;
                            $("#dialog").dialog("close");
                        }
                    });
                    return false;
            }

but it is skipping right over the success callback function, and the browser asks if I would like to download the json file. Here's a peek at my upload action:

 [HttpPost]
        public ActionResult Upload(HttpPostedFileBase file)
        {
            Regex imageFilenameRegex = new Regex(@"(.*?)\.(jpg|jpeg|png|gif)$");
            if (file != null)
            {
                if (!imageFilenameRegex.IsMatch(file.FileName))
                {
                    return JavaScript("alert('invalid file. you must upload a jpg, jpeg, png, or gif');");
                }
                else
                {
                    string filePath = Path.Combine(HttpContext.Server.MapPath("~/Uploads"), Path.GetFileName(file.FileName));
                    file.SaveAs(filePath);

                    return Json(new { FileName = "/Uploads/" + file.FileName });
                }
            }
            else
            {
                return JavaScript("alert('seriously? select a file to upload before hitting the upload button.');");
            }
        }

I've used jQuery.post and it will hit the controller action but file will be null, but at least errors would pop up in their alert boxes, so that is why I sought out another option. Now it hits the controller action and the file gets uploaded, but it isn't handling any response. Any help is appreciated, thanks.

A: 

If you want to do ajax uploads, you are going to want do the upload form inside an iframe.

See: http://www.ajaxf1.com/tutorial/ajax-file-upload-tutorial.html

Sam Saffron
I use a multiple-file ajax-based upload elsewhere in my project and it works great without your iFrames. I would prefer to get this success callback working, because the upload portion itself is working fine.
Gallen
The only way to do it without an iFrame is using flash AFAIK http://stackoverflow.com/questions/543926/is-it-possible-to-ajax-a-file-upload
Sam Saffron
I just looked through the script - this one rebuilds my form with an iframe and then does the upload. So...any ideas on the callback?
Gallen
I think that plugin is expecting the return value to be text, have you tried simply returning the results as XML or text (not json)
Sam Saffron
+2  A: 

The plugin you are using expects text/html as response Content Type even if you are passing JSON. So if you really want to use it you need to do this:

return Content("{ FileName: '/Uploads/' }", "text/html");

As you understand that's crap.

So go ahead and download the jquery form plugin. It's much easier to use. You don't have to do anything in your HTML, it's totally unobtrusive. Just leave the form as is and in javascript simply:

$(function() {
    // Only indicate the form id, it will take care of reading the form action, 
    // returning false, ..., all you need is to concentrate 
    // on the success callback
    $('#uploadForm').ajaxForm(function(result) {
        alert(result);
    });
});

Also notice that in case of error you shouldn't return Javascript. You always need to return Json from your controller action. So in case of error:

return Json(new { errorMessage = "Kaboom", fileName = "" });

and in case of success:

return Json(new { errorMessage = "", fileName = "/Uploads/" + file.FileName });

so now you can check whether there's an error by inspecting the errorMessage property on the returned JSON object:

$('#uploadForm').ajaxForm(function(result) {
    if (result.errorMessage != '') {
        alert(result.errorMessage);
    } else {
        $('#RelatedFileName').val(result.fileName);
        $('#dialog').dialog('close');
    }
});
Darin Dimitrov
You always have the best advice, Darin - thanks again.
Gallen