最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - HTML5 asynchronous file upload, uploaded stream is always invalid - Stack Overflow

programmeradmin2浏览0评论

I'm trying to debug an asynchronous file uploader that I built some time ago which is no longer working, I've spent already a good deal of time without success.

The stream that the server is receiving is always corrupted in fact the file (image) that I save cannot be opened.

To simplify debugging I have setup a brand new ASP.NET project, with two main files, the HTML file with the form field and the ASP.NET handler.

Despite the code here being very trivial, I'm still out of luck! :(

Any help is highly appreciated, many thanks!

<!DOCTYPE html>
<html>
<head>
    <title>Upload Files using XMLHttpRequest - Minimal</title>

    <script type="text/javascript">

      function uploadFile() {
        var fd = new FormData();
        fd.append("fileToUpload", document.getElementById('fileToUpload').files[0]);
        var xhr = new XMLHttpRequest();

        xhr.addEventListener("load", uploadComplete, false);
        xhr.addEventListener("error", uploadFailed, false);
        xhr.addEventListener("abort", uploadCanceled, false);
        xhr.open("POST", "Handler1.ashx");
        xhr.send(fd);
      }

      function uploadComplete(evt) {
        /* This event is raised when the server send back a response */
        alert(evt.target.responseText);
      }

      function uploadFailed(evt) {
        alert("There was an error attempting to upload the file.");
      }

      function uploadCanceled(evt) {
        alert("The upload has been canceled by the user or the browser dropped the connection.");
      }
    </script>
</head>
<body>
  <form id="form1" enctype="multipart/form-data" method="post" action="Handler1.ashx">

      <input type="file" name="fileToUpload" id="fileToUpload"/>
      <input type="button" onclick="uploadFile()" value="Upload" />

  </form>
</body>
</html>

and here is the ashx handler:

using System;
using System.Collections.Generic;
using System.Web.Extensions;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.IO;
namespace MultipleFileUploadTest
{
    [WebService(Namespace = "/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class Handler1 : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            var stream = context.Request.InputStream;

            MemoryStream memoryStream;

            ReadFully(stream, out memoryStream);

            Byte[] ba = memoryStream.ToArray();


            var path = @"C:\Users\giuseppe.JHP\Desktop\Image upload test\uploaded.gif";


            using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate))
            {
                fs.Write(ba, 0, ba.Length);
            }

            //DEBUGGING CODE
            //I'm opening the same file that was originally picked by the input form field and I'm now paring the original file with the one received within the context stream. They always differ!
            Byte[] ba2 = File.ReadAllBytes(@"C:\Users\giuseppe.JHP\Desktop\Image upload test\a.gif");

            //equal evaluates always to false
            bool equal = ba.Length == ba2.Length;

            if (equal)
            {
                for (var i = 0; i < ba2.Length; i++)
                {
                    if (ba[i] != ba2[i])
                    {
                        equal = false;
                        i = ba2.Length;
                    }
                }

            }

            //equal is always false
            //if (!equal)
            //{
            //   throw Exception("Stream is not valid");
            //}
            //The code below will throw a Parameter is invalid exception
            //System.Drawing.Image mediaObject = System.Drawing.Image.FromStream(memoryStream);


            memoryStream.Close();
        }

        public static void ReadFully(Stream input, out MemoryStream ms)
        {
            ms = new MemoryStream();
            byte[] buffer = new byte[16 * 1024];

            int read;
            while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
        }
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

I'm trying to debug an asynchronous file uploader that I built some time ago which is no longer working, I've spent already a good deal of time without success.

The stream that the server is receiving is always corrupted in fact the file (image) that I save cannot be opened.

To simplify debugging I have setup a brand new ASP.NET project, with two main files, the HTML file with the form field and the ASP.NET handler.

Despite the code here being very trivial, I'm still out of luck! :(

Any help is highly appreciated, many thanks!

<!DOCTYPE html>
<html>
<head>
    <title>Upload Files using XMLHttpRequest - Minimal</title>

    <script type="text/javascript">

      function uploadFile() {
        var fd = new FormData();
        fd.append("fileToUpload", document.getElementById('fileToUpload').files[0]);
        var xhr = new XMLHttpRequest();

        xhr.addEventListener("load", uploadComplete, false);
        xhr.addEventListener("error", uploadFailed, false);
        xhr.addEventListener("abort", uploadCanceled, false);
        xhr.open("POST", "Handler1.ashx");
        xhr.send(fd);
      }

      function uploadComplete(evt) {
        /* This event is raised when the server send back a response */
        alert(evt.target.responseText);
      }

      function uploadFailed(evt) {
        alert("There was an error attempting to upload the file.");
      }

      function uploadCanceled(evt) {
        alert("The upload has been canceled by the user or the browser dropped the connection.");
      }
    </script>
</head>
<body>
  <form id="form1" enctype="multipart/form-data" method="post" action="Handler1.ashx">

      <input type="file" name="fileToUpload" id="fileToUpload"/>
      <input type="button" onclick="uploadFile()" value="Upload" />

  </form>
</body>
</html>

and here is the ashx handler:

using System;
using System.Collections.Generic;
using System.Web.Extensions;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.IO;
namespace MultipleFileUploadTest
{
    [WebService(Namespace = "http://tempuri/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class Handler1 : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            var stream = context.Request.InputStream;

            MemoryStream memoryStream;

            ReadFully(stream, out memoryStream);

            Byte[] ba = memoryStream.ToArray();


            var path = @"C:\Users\giuseppe.JHP\Desktop\Image upload test\uploaded.gif";


            using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate))
            {
                fs.Write(ba, 0, ba.Length);
            }

            //DEBUGGING CODE
            //I'm opening the same file that was originally picked by the input form field and I'm now paring the original file with the one received within the context stream. They always differ!
            Byte[] ba2 = File.ReadAllBytes(@"C:\Users\giuseppe.JHP\Desktop\Image upload test\a.gif");

            //equal evaluates always to false
            bool equal = ba.Length == ba2.Length;

            if (equal)
            {
                for (var i = 0; i < ba2.Length; i++)
                {
                    if (ba[i] != ba2[i])
                    {
                        equal = false;
                        i = ba2.Length;
                    }
                }

            }

            //equal is always false
            //if (!equal)
            //{
            //   throw Exception("Stream is not valid");
            //}
            //The code below will throw a Parameter is invalid exception
            //System.Drawing.Image mediaObject = System.Drawing.Image.FromStream(memoryStream);


            memoryStream.Close();
        }

        public static void ReadFully(Stream input, out MemoryStream ms)
        {
            ms = new MemoryStream();
            byte[] buffer = new byte[16 * 1024];

            int read;
            while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
        }
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}
Share Improve this question edited Mar 7, 2012 at 11:57 Giuseppe Romagnuolo asked Mar 6, 2012 at 18:02 Giuseppe RomagnuoloGiuseppe Romagnuolo 3,4122 gold badges31 silver badges38 bronze badges 2
  • 2 That is what a Ctrl + K + D does in VS, I've not spend much time to format it further to be honest! – Giuseppe Romagnuolo Commented Mar 6, 2012 at 18:19
  • 2 @llnk new line for C# is pretty standard. I was always taught not to write code "With an accent", and Giuseppe is actually following pretty standard code conventions here. – Chris Pfohl Commented Jan 14, 2013 at 14:56
Add a ment  | 

1 Answer 1

Reset to default 5

In case it helped someone else, I've got the code to work, here is what it is changed:

    public void ProcessRequest(HttpContext context)
    {
        if (context.Request.Files != null && context.Request.Files.Count > 0)
        {
            var file = context.Request.Files[0];

            file.SaveAs(@"C:\Users\giuseppe.JHP\Desktop\Image upload test\uploaded.gif");
        }
    }
发布评论

评论列表(0)

  1. 暂无评论