【问题标题】:File API File Upload - Read XMLHttpRequest in ASP.NET MVC文件 API 文件上传 - 在 ASP.NET MVC 中读取 XMLHttpRequest
【发布时间】:2011-07-08 02:18:52
【问题描述】:

我正在尝试在 ASP.NET MVC 中实现 Gmail 样式的拖放文件上传。

我一直在关注这篇文章:http://robertnyman.com/html5/fileapi-upload/fileapi-upload.html 并希望将上传的文件发布到 MVC 控制器操作。

为此,我修改了链接中的示例 JavaScript 脚本以指向我的控制器操作:

xhr.open("post", "/home/UploadFiles", true);

这是我的控制器操作:

[HttpPost]
public virtual string UploadFiles(object obj)
{
    var length = Request.ContentLength;
    var bytes = new byte[length];
    Request.InputStream.Read(bytes, 0, length);
    // var bytes has byte content here. what do do next?

    return "Files uploaded!";
}

我设置了一个断点,当我上传一个文件时,断点被命中——这很好。但是如何从上传的(javascript)XMLHttpRequest 对象中提取数据?我不认为它在 HttpRequest - 它是参数吗?如果是这样,我应该期望什么类型以及如何提取字节数组并从中提取上传的文件信息?

(我使用的是 Chrome - 我知道它在 IE 中不起作用)

任何建议将不胜感激!

【问题讨论】:

    标签: jquery asp.net-mvc file-upload


    【解决方案1】:

    想通了。这是 C# 代码:

    [HttpPost]
        public virtual string UploadFiles(object obj)
        {
            var length = Request.ContentLength;
            var bytes = new byte[length];
            Request.InputStream.Read(bytes, 0, length);
            // bytes has byte content here. what do do next?
    
            var fileName = Request.Headers["X-File-Name"];
            var fileSize = Request.Headers["X-File-Size"];
            var fileType = Request.Headers["X-File-Type"];
    
            var saveToFileLoc = string.Format("{0}\\{1}",
                                           Server.MapPath("/Files"),
                                           fileName);
    
            // save the file.
            var fileStream = new FileStream(saveToFileLoc, FileMode.Create, FileAccess.ReadWrite);
            fileStream.Write(bytes, 0, length);
            fileStream.Close();
    
            return string.Format("{0} bytes uploaded", bytes.Length);
        }
    

    这里是 Javascript 代码:

    <script type="text/javascript">
    (function ()
    {
        var filesUpload = document.getElementById("files-upload");
        var dropArea = document.getElementById("drop-area");
        var fileList = document.getElementById("file-list");
    
        function uploadFile(file)
        {
            var li = document.createElement("li");
            var progressBarContainer = document.createElement("div");
            var progressBar = document.createElement("div");
    
            progressBarContainer.className = "progress-bar-container";
            progressBar.className = "progress-bar";
            progressBarContainer.appendChild(progressBar);
            li.appendChild(progressBarContainer);
    
            // Uploading - for Firefox, Google Chrome and Safari
            var xhr = new XMLHttpRequest();
    
            // Update progress bar
            xhr.upload.addEventListener("progress", function (evt)
            {
                if (evt.lengthComputable)
                {
                    progressBar.style.width = (evt.loaded / evt.total) * 100 + "%";
                }
            }, false);
    
            // File uploaded
            xhr.addEventListener("load", function ()
            {
                progressBarContainer.className += " uploaded";
                progressBar.innerHTML = "Uploaded!";
            }, false);
    
            xhr.open("post", "/home/UploadFile", true);
    
            // Set appropriate headers
            xhr.setRequestHeader("Content-Type", "multipart/form-data");
            xhr.setRequestHeader("X-File-Name", file.fileName);
            xhr.setRequestHeader("X-File-Size", file.fileSize);
            xhr.setRequestHeader("X-File-Type", file.type);
    
            // Send the file
            xhr.send(file);
    
            // Present file info and append it to the list of files
            var div = document.createElement("div");
            li.appendChild(div);
            var fileInfo = "<div><strong>Name:</strong> " + file.name + "</div>";
            fileInfo += "<div><strong>Size:</strong> " + parseInt(file.size / 1024, 10) + " kb</div>";
            fileInfo += "<div><strong>Type:</strong> " + file.type + "</div>";
            div.innerHTML = fileInfo;
    
            // insert at beginning of list.
            fileList.insertBefore(li, fileList.firstChild);
    
            // or insert at end of list.
            //fileList.appendChild(li);
        }
    
        function traverseFiles(files)
        {
            if (typeof files !== "undefined")
            {
                for (var i = 0, l = files.length; i < l; i++)
                {
                    uploadFile(files[i]);
                }
            }
            else
            {
                fileList.innerHTML = "No support for the File API in this web browser";
            }
        }
    
        filesUpload.addEventListener("change", function ()
        {
            traverseFiles(this.files);
        }, false);
    
        dropArea.addEventListener("dragleave", function (evt)
        {
            var target = evt.target;
    
            if (target && target === dropArea)
            {
                this.className = "";
            }
            evt.preventDefault();
            evt.stopPropagation();
        }, false);
    
        dropArea.addEventListener("dragenter", function (evt)
        {
            this.className = "over";
            evt.preventDefault();
            evt.stopPropagation();
        }, false);
    
        dropArea.addEventListener("dragover", function (evt)
        {
            evt.preventDefault();
            evt.stopPropagation();
        }, false);
    
        dropArea.addEventListener("drop", function (evt)
        {
            //document.getElementById("file-list").innerHTML = "";
    
            traverseFiles(evt.dataTransfer.files);
            this.className = "";
            evt.preventDefault();
            evt.stopPropagation();
        }, false);
    })();
    

    【讨论】:

    • 我假设保存请求 byte[] 将是一个 XML 文档,而不是文件内容本身。结果比我预期的要简单得多。
    • 当我尝试使用此代码时。如果我尝试上传图片,我会得到错误的文件
    • @WeekendWarrior 当我尝试上传图像时,您添加的标题已存储在图像中。如何从文件中删除这些标题?
    • 请注意,您不需要发送X-File-Size 标头,因为Request.ContentLength 包含文件的长度。
    【解决方案2】:

    这很棒。略有改进:

    xhr.setRequestHeader("X-File-Name", file.name);
    xhr.setRequestHeader("X-File-Size", file.size);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 2014-05-13
      • 2012-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-06
      相关资源
      最近更新 更多