Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using plupload with MVC3

So, I've implemented plupload using flash runtime in MVC3.

It works perfectly, in the sense that it uploads using the correction Action and runs it all. However, I'd really like to be able to control the response, and handle it in plupload, but I can't seem to get any response through.

I've tried overriding fileUploaded, but I can't seem to get anything out of the arguments. I've tried return simple strings, json and what have you. I can't seem to get anything out on the client side. And of course being sent through flash, I can't even debug the requests with firebug :/

The same with the Error event, and throwing exceptions. It correctly interprets the exception as an error, but it's always that #IO ERROR with some code like 2038 or something coming out the other end. I can't show my exception string or anything at all. Can anyone help?

Bonus question: How would I send session/cookie data along with the plupload, so I can access the session in my action?

like image 646
Dynde Avatar asked May 23 '11 07:05

Dynde


2 Answers

The following has worked for me:

[HttpPost]
public ActionResult Upload(int? chunk, string name)
{
    var fileUpload = Request.Files[0];
    var uploadPath = Server.MapPath("~/App_Data");
    chunk = chunk ?? 0;
    using (var fs = new FileStream(Path.Combine(uploadPath, name), chunk == 0 ? FileMode.Create : FileMode.Append))
    {
        var buffer = new byte[fileUpload.InputStream.Length];
        fileUpload.InputStream.Read(buffer, 0, buffer.Length);
        fs.Write(buffer, 0, buffer.Length);
    }
    return Json(new { message = "chunk uploaded", name = name });
}

and on the client:

$('#uploader').pluploadQueue({
    runtimes: 'html5,flash',
    url: '@Url.Action("Upload")',
    max_file_size: '5mb',
    chunk_size: '1mb',
    unique_names: true,
    multiple_queues: false,
    preinit: function (uploader) {
        uploader.bind('FileUploaded', function (up, file, data) {
            // here file will contain interesting properties like 
            // id, loaded, name, percent, size, status, target_name, ...
            // data.response will contain the server response
        });
    }
});

As far as the bonus question is concerned I am willing to answer it by don't use sessions, as they don't scale well, but because I know that you probably won't like this answer you have the possibility to pass a session id in the request using the multipart_params:

multipart_params: {
    ASPSESSID: '@Session.SessionID'
},

and then on the server perform some hacks to create the proper session.

like image 69
Darin Dimitrov Avatar answered Nov 09 '22 06:11

Darin Dimitrov


Look here:

$("#uploader").pluploadQueue({
         // General settings
         runtimes: 'silverlight',
         url: '/Home/Upload',
         max_file_size: '10mb',
         chunk_size: '1mb',
         unique_names: true,
         multiple_queues: false,

         // Resize images on clientside if we can
         resize: { width: 320, height: 240, quality: 90 },

         // Specify what files to browse for
         filters: [
            { title: "Image files", extensions: "jpg,gif,png" },
            { title: "Zip files", extensions: "zip" }
        ],

         // Silverlight settings
         silverlight_xap_url: '../../../Scripts/upload/plupload.silverlight.xap'
      });

      // Client side form validation
      $('form').submit(function (e) {
         var uploader = $('#uploader').pluploadQueue();

         // Files in queue upload them first
         if (uploader.files.length > 0) {
            // When all files are uploaded submit form
            uploader.bind('StateChanged', function () {
               if (uploader.files.length === (uploader.total.uploaded + uploader.total.failed)) {
                  $('form')[0].submit();
               }
            });

            uploader.start();
         } else {
            alert('You must queue at least one file.');
         }

         return false;
      });

And in Controller:

[HttpPost]
public string Upload(  ) {
          HttpPostedFileBase FileData = Request.Files[0];

          if ( FileData.ContentLength > 0 ) {
             var fileName = Path.GetFileName( FileData.FileName );
             var path = Path.Combine( Server.MapPath( "~/Content" ), fileName );
             FileData.SaveAs( path );
          }

          return "Files was uploaded successfully!";
       }

That's all...No chunk is needed in Controller...

like image 5
Snake Eyes Avatar answered Nov 09 '22 06:11

Snake Eyes