How do I get jQuery's Uploadify plugin to work with ASP.NET MVC?

26,483

Solution 1

public string Upload(HttpPostedFileBase FileData) {}

is correct - the file uploaded by uploadify will get binded to FileData. No need to get into Request.Files to retrieve the file - which makes it harder to mock and test.

If your action isn't firing at all (i.e. try debugging and see if a breakpoint within the method is hit), then your issue is most likely the 'script' value - are you running under a virtual directory? If so you'll need to put the name of the directory in front. Uploadify is using an absolute path.

i.e. 'script: '/virtual_directory/Placement/Upload'

right now uploadify is sending to http://localhost/Placement/Upload.

also try using the route debugger (http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx) to check where your route is being mapped to.

Solution 2

The problem might be that you need to specify that the action you are uploading to is set to Post...it won't work with the action as a Get action.

So, this:

public string Upload(HttpPostedFileBase FileData)
{
   //do something
}

Should be this:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Upload(HttpPostedFileBase FileData)
{
   //do something
}

Also, be aware that if you are using this in a "logged in" section of your site, you should take a look here for a known bug with uploadify and authentication: http://geekswithblogs.net/apopovsky/archive/2009/05/06/working-around-flash-cookie-bug-in-asp.net-mvc.aspx

Also, just an aside, there are several ways in MVC to handle file uploads (using Request.Files as per Rory Fitzpatrick's suggestion, as well as passing the HttpPostedFileBase file as an argument in the action definition). It shouldn't really matter in order to get Uploadify to work.

Solution 3

This isn't how I had to implement file upload at all. I had an action method with no parameters that used the current Request object to dive into the collection of posted files.

Some sample code from my implementation:

[AcceptVerbs(HttpVerbs.Post)]
public ContentResult Upload() {
    if (Request.Files.Count > 0 && Request.Files[0].ContentLength > 0) {
        HttpPostedFileBase postedFile = Request.Files[0];
        // Do something with it
    }
}

Of course, writing tests for this becomes a PITA. You have to mock several objects in order to get it to work, for example:

var mockHttpContext = mocks.StrictMock<HttpContextBase>();
var mockRequest = mocks.StrictMock<HttpRequestBase>();
var postedFile = mocks.StrictMock<HttpPostedFileBase>();

var postedFileKeyCollection = mocks.StrictMock<HttpFileCollectionBase>();

mockHttpContext.Expect(x => x.Request).Return(mockRequest).Repeat.Any();
mockRequest.Expect(x => x.Files).Return(postedFileKeyCollection).Repeat.Any();

postedFileKeyCollection.Expect(x => x[0]).Return(postedFile).Repeat.Any();
postedFileKeyCollection.Expect(x => x.Count).Return(1);

postedFile.Expect(f => f.ContentLength).Return(1024);
postedFile.Expect(f => f.InputStream).Return(null);

It would be easier to create an interface into the posted files and only mock that, with a concrete implementation injected into your controller using IoC.

I think this was largely based off of this post: Implementing HTTP File Upload with ASP.NET MVC including Tests and Mocks

Solution 4

My full solution to this might solve your problem. Hope it helps.

http://zootfroot.blogspot.com/2010/12/mvc-file-upload-using-uploadify-with.html

Share:
26,483
KingNestor
Author by

KingNestor

CS Student at the University of Central Missouri

Updated on September 07, 2020

Comments

  • KingNestor
    KingNestor over 3 years

    I'm in the process of trying to get the jQuery plugin, Uploadify, to work with ASP.NET MVC.

    I've got the plugin showing up fine with the following JavaScript snippet:

    <script type="text/javascript">
        $(document).ready(function() {
            $('#fileUpload').fileUpload({
                'uploader': '/Content/Flash/uploader.swf',
                'script': '/Placement/Upload',
                'folder': '/uploads',
                'multi': 'true',
                'buttonText': 'Browse',
                'displayData': 'speed',
                'simUploadLimit': 2,
                'cancelImg': '/Content/Images/cancel.png'
            });
        });
    </script>
    

    Which seems like all is well in good. If you notice, the "script" attribute is set to my /Placement/Upload, which is my Placement Controller and my Upload Action.

    The main problem is, I'm having difficulty getting this action to fire to receive the file. I've set a breakpoint on that action and when I select a file to upload, it isn't getting executed.

    I've tried changing the method signature based off this article:

    public string Upload(HttpPostedFileBase FileData)
    {
        /*
        *
        * Do something with the FileData
        *
        */
        return "Upload OK!";
    }
    

    But this still doesn't fire.

    Can anyone help me write and get the Upload controller action's signature correctly so it will actually fire? I can then handle dealing with the file data myself. I just need some help getting the method action to fire.

  • Jack Marchetti
    Jack Marchetti about 13 years
    Yeah he's asking about Uploadify, not using the regular upload process.