40

I'm trying to use valums ajax uploader. http://valums.com/ajax-upload/

I have the following on my page:

var button = $('#fileUpload')[0];
var uploader = new qq.FileUploader({
    element: button,
    allowedExtensions: ['jpg', 'jpeg', 'png', 'gif'], 
    sizeLimit: 2147483647, // max size
    action: '/Admin/Home/Upload',
    multiple: false
});

it does post to my controller but qqfile is always null. I tried these:

public ActionResult Upload(HttpPostedFile qqfile)
AND
HttpPostedFileBase file = Request.Files["file"];

without any luck.

I found an example for ruby on rails but not sure how to implement it in MVC http://www.jigsawboys.com/2010/10/06/ruby-on-rails-ajax-file-upload-with-valum/

In firebug i see this: http://localhost:61143/Admin/Home/Upload?qqfile=2glonglonglongname+-+Copy.gif

enter image description here

enter image description here enter image description here

enter image description here

ShaneKm
  • 20,823
  • 43
  • 167
  • 296
  • Those crazy characters you're seeing could be because of this same reason - http://stackoverflow.com/questions/3183203/asp-net-mvc2-crazy-characters-in-view-output-wtf – Chase Florell Oct 14 '11 at 21:45
  • I have posted the following https://github.com/valums/ajax-upload/issues/100 – Valamas May 23 '12 at 00:35

5 Answers5

68

I figured it out. this works in IE and Mozilla.

    [HttpPost]
    public ActionResult FileUpload(string qqfile)
    {
        var path = @"C:\\Temp\\100\\";
        var file = string.Empty;

        try
        {
            var stream = Request.InputStream;
            if (String.IsNullOrEmpty(Request["qqfile"]))
            {
                // IE
                HttpPostedFileBase postedFile = Request.Files[0];
                stream = postedFile.InputStream;
                file = Path.Combine(path, System.IO.Path.GetFileName(Request.Files[0].FileName));
            }
            else
            {
                //Webkit, Mozilla
                file = Path.Combine(path, qqfile);
            }

            var buffer = new byte[stream.Length];
            stream.Read(buffer, 0, buffer.Length);
            System.IO.File.WriteAllBytes(file, buffer);
        }
        catch (Exception ex)
        {
            return Json(new { success = false, message = ex.Message }, "application/json");
        }

       return Json(new { success = true }, "text/html");
    }
ShaneKm
  • 20,823
  • 43
  • 167
  • 296
  • 1
    This should be marked as the answer, since it's more complete. Nice work Shane, totally helped me out. – Jason Slocomb Feb 21 '11 at 09:43
  • 1
    I'd agree. I wrote a more complete reusable solution, but the above does the same. – Simon Halsey Feb 24 '11 at 13:25
  • 1
    Only problem: the whole file is being buffered in memory. what if its a 2GB video? Better to take smaller (100kB) chunks from the stream and write that to a file stream before getting next chunk etc. – saille Apr 13 '11 at 21:00
  • 7
    It appears (at least for me) that IE doesn't like the "application/json" content type, as it requests to download the result. Using "text/html" seems to work for both. Just FYI if someone else runs into the same problem – Chris Curtis Jun 10 '11 at 22:17
  • this solution is the most complete I've seen and the most reliable. Thanks so much :D – Pure Function Aug 15 '12 at 23:46
  • @Chris Great! You saved a whole lot of headache! – Adrian Marinica Aug 21 '12 at 12:24
1

You should try:

Stream inputStream = (context.Request.Files.Count > 0) ? context.Request.Files[0].InputStream : context.Request.InputStream;
bob
  • 11
  • 1
1

This component is sending an application/octet-stream instead of multipart/form-data which is what the default model binder can work with. So you cannot expect Request.Files to have any value with such a request.

You will need to manually read the request stream:

public ActionResult Upload(string qqfile)
{
    var stream = Request.InputStream;
    var buffer = new byte[stream.Length];
    stream.Read(buffer, 0, buffer.Length);

    var path = Server.MapPath("~/App_Data");
    var file = Path.Combine(path, qqfile);
    File.WriteAllBytes(file, buffer);

    // TODO: Return whatever the upload control expects as response
}
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • I fount this: but i can't figure out how to implement it: IE doesn't send the stream in "request.InputStream" ... instead get the input stream through the HttpPostedFileBase from the Request.Files[] collection. – ShaneKm Feb 03 '11 at 13:50
1

IE uploads using multipart-mime. Other browsers use Octet-Stream.

I wrote an upload handler to work with Valums Ajax Uploader that works with both MVC & Webforms & both upload methods. I'd be happy to share with you if you wanted. It closely follows the the PHP handler.

My controller to handle the upload looks like this:

public class UploadController : Controller
{
    private IUploadService _Service;

    public UploadController()
        : this(null)
    {
    }

    public UploadController(IUploadService service)
    {
        _Service = service ?? new UploadService();
    }

    public ActionResult File()
    {
        return Content(_Service.Upload().ToString());
    }

The UploadService looks this:

public class UploadService : IUploadService
{
    private readonly qq.FileUploader _Uploader;

    public UploadService()
        : this(null)
    { }

    public UploadService(IAccountService accountservice)
    {
        _Uploader = new qq.FileUploader();
    }

    public UploadResult Upload()
    {
        qq.UploadResult result = _Uploader.HandleUpload();
        if (!result.Success)
            return new UploadResult(result.Error);

                     .... code .....

        return new UploadResult((Guid)cmd.Parameters["@id"].Value);
        }
        catch (Exception ex)
        {
            return new UploadResult(System.Web.HttpUtility.HtmlEncode(ex.Message));
        }
        finally
        {
                      ............code.........
        }

    }

   ...............code ............
Simon Halsey
  • 5,459
  • 1
  • 21
  • 32
0

I am developing in ASP.Net 4.0 but we don't have MVC architecture. I had same issue few days back. But, I figured it out and here is my solution.

//For IE Browser
HttpPostedFile selectedfile = Request.Files[0];
System.Drawing.Bitmap obj = new System.Drawing.Bitmap(selectedfile.InputStream);

//For Non IE Browser
System.Drawing.Bitmap obj = new System.Drawing.Bitmap(Request.InputStream);

Now, you can use obj for further operation.

Gaurang Jadia
  • 1,516
  • 15
  • 18