需要帮助调试XHR基础的Ajax图片上传与ASP.NET MVC2 [英] Need help debugging XHR-based Ajax Image Upload with ASP.NET MVC2

查看:102
本文介绍了需要帮助调试XHR基础的Ajax图片上传与ASP.NET MVC2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用发现从 http://valums.com/ajax-upload/

我的控制器如下:

 使用系统;
使用System.IO;
使用System.Text.RegularEx pressions;
使用的System.Web;
使用System.Web.Hosting;
使用System.Web.Mvc;
使用MHNHub.Areas.ViewModels;
使用MHNHub.Models;
使用MHNHub.ViewModels;

命名空间MHNHub.Areas.Admin.Controllers
{
    [授权(角色=管理员)
    公共类ImageController:控制器
    {

        私人MHNHubEntities _entities =新MHNHubEntities();

        //
        // GET:/图像/
        的[AcceptVerbs(HttpVerbs.Get)
        公众的ActionResult ImageUploader()
        {
            VAR视图模型=新ImageViewModel()
            {
                图片=新的图像()
            };

            返回PartialView(视图模型);
        }

        的[AcceptVerbs(HttpVerbs.Post)
        公众的ActionResult ImageUploader(形象画像)
        {
            尝试
            {
                _entities.Images.AddObject(图像);
                _entities.SaveChanges();

                返回RedirectToAction(指数,产品);
            }
            赶上(例外前)
            {
                VAR视图模型=新ImageViewModel()
                                {
                                    图片=形象,
                                    HasError = TRUE,
                                    的ErrorMessage = ex.Message
                                };
                返回PartialView(视图模型);

            }
        }

        私人字符串_uploadsFolder = HostingEnvironment.MapPath(〜/ App_Data文件/文件);

        公众的Guid上传(HttpPostedFileBase fileBase)
        {
            变种标识符= Guid.NewGuid();
            fileBase.SaveAs(GetDiskLocation(标识));
            返回标识;
        }

        私人字符串GetDiskLocation(GUID标识符)
        {
            返回Path.Combine(_uploadsFolder,identifier.ToString());
        }

    }

}
 

和我有这样的局部视图

 <%@控制语言=C#继承=System.Web.Mvc.ViewUserControl< MHNHub.ViewModels.ImageViewModel>中%>

<脚本类型=文/ JavaScript的>
    $(函数(){
        $(#imagedialog)。对话框({
            bgiframe:真正的,
            高度:170,
            宽度:430,
            模式:真正的,
            的AutoOpen:假的,
            可调整大小:真
        })
    });

    $(文件)。就绪(函数createUploader(){
        VAR上传=新qq.FileUploader({
            元素:的document.getElementById('fileuploader),
            动作:/图片/上传/',
            名称:名称
        });

    });

< / SCRIPT>

< D​​IV ID =imagedialog称号=上传图片>

                < D​​IV ID =fileuploader>

                < / DIV>
                < H6>拖放启用支持在Firefox和谷歌浏览器的JavaScript文件< / H6>
                    < NOSCRIPT>
                         <形式的行动=/图片/上传ENCTYPE =多部分/表单数据的方法=邮报>
                            选择一个文件:其中;输入类型=文件名称=照片ID =照片/>

                            <输入类型=提交值=上传NAME =提交/>
                        < /形式GT;
                    < / NOSCRIPT>


< / DIV>

< D​​IV CLASS =主编场>
    &所述; IMG SRC =&其中;%:Model.Image.FileName%>中/>
    <%:Html.TextBoxFor(型号=> model.Image.FileName)%>
    <%:Html.ValidationMessageFor(型号=> model.Image.FileName)%>
    < A HREF =#的onclick =的jQuery('#imagedialog)对话框(公开);返回false>上传图片< / A>
< / DIV>
 

我有fileuploader.js和fileuploader.css母版页上适当的联系,并上载正确显示,其甚至称我的行为,但HttpPostedFileBase为null,并且上传操作抛出一个异常。任何见解,以我应该怎么办?

修改

所以,我已经想通了使用萤火虫其发送XmlHtt prequest。在我的上载操作如何处理呢?

解决方案

你得到一个空的参数,在控制器动作的原因是因为这个插件不发送的multipart / form-data的请求到服务器。相反,它发送应用程序/八位字节流内容类型的请求头,并直接将数据写入文件内容请求流,附加参数?qqfile 包含文件名的URL。所以,如果你想取出这个控制器上,您将需要直接读取流:

  [HttpPost]
公众的ActionResult上传(字符串qqfile)
{
    使用(VAR读卡器= BinaryReader在新(Request.InputStream))
    {
        //这将包含上传的文件数据和qqfile名
        byte []的文件= reader.ReadBytes((INT)Request.InputStream.Length);
    }
    返回查看();
}
 

如果您选择了多个文件的插件,只需发送多个请求到服务器,所以这将正常工作。

如果你要处理的文件大于 int.MaxValue 则必须从请求流中的块来直接读写装载的输出流,而不是还整个文件到内存缓冲区:

 使用(VAR的OutputStream = File.Create(qqfile))
{
    const int的CHUNKSIZE = 2 * 1024; // 2KB
    byte []的缓冲区=新的字节[CHUNKSIZE]
    INT读取动作;
    而((读取动作= Request.InputStream.Read(缓冲液,0,buffer.Length))大于0)
    {
        outputStream.Write(缓冲液,0,读取动作);
    }
}
 

注:从你的的document.ready 删除 createUploader 函数名称。它应该是一个匿名函数存在。你甚至可以用它合并了 $(函数(){...}); 您已经设置了模态对话框

I'm attempting to use the script found from http://valums.com/ajax-upload/

My controller is as follows

using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Hosting;
using System.Web.Mvc;
using MHNHub.Areas.ViewModels;
using MHNHub.Models;
using MHNHub.ViewModels;

namespace MHNHub.Areas.Admin.Controllers
{
    [Authorize(Roles = "Administrator")]
    public class ImageController : Controller
    {

        private MHNHubEntities _entities = new MHNHubEntities();

        //
        // GET: /Image/
        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult ImageUploader()
        {
            var viewModel = new ImageViewModel()
            {
                Image = new Image()
            };

            return PartialView(viewModel);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult ImageUploader(Image image)
        {
            try
            {
                _entities.Images.AddObject(image);
                _entities.SaveChanges();

                return RedirectToAction("Index", "Product");
            }
            catch (Exception ex)
            {
                var viewModel = new ImageViewModel()
                                {
                                    Image = image,
                                    HasError = true,
                                    ErrorMessage = ex.Message
                                };
                return PartialView(viewModel);

            }
        }

        private string _uploadsFolder = HostingEnvironment.MapPath("~/App_Data/Files");

        public Guid Upload(HttpPostedFileBase fileBase)
        {
            var identifier = Guid.NewGuid();
            fileBase.SaveAs(GetDiskLocation(identifier));
            return identifier;
        }

        private string GetDiskLocation(Guid identifier)
        {
            return Path.Combine(_uploadsFolder, identifier.ToString());
        }

    }

}

And I have a partial view like this

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MHNHub.ViewModels.ImageViewModel>" %>

<script type="text/javascript">
    $(function () {
        $("#imagedialog").dialog({
            bgiframe: true,
            height: 170,
            width: 430,
            modal: true,
            autoOpen: false,
            resizable: true
        })
    });

    $(document).ready(function createUploader() {
        var uploader = new qq.FileUploader({
            element: document.getElementById('fileuploader'),
            action: '/Image/Upload/',
            name: 'name'
        });

    });

</script>    

<div id="imagedialog" title="Upload Image">

                <div id="fileuploader">

                </div>
                <h6>Drag and drop files supported in Firefox and Google Chrome with javascript enabled.</h6> 
                    <noscript>
                         <form action="/image/upload" enctype="multipart/form-data" method="post">
                            Select a file: <input type="file" name="photo" id="photo" />   

                            <input type="submit" value="Upload" name="submit"/>
                        </form>
                    </noscript>


</div>

<div class="editor-field">
    <img src="<%: Model.Image.FileName %>" />
    <%: Html.TextBoxFor(model => model.Image.FileName) %>
    <%: Html.ValidationMessageFor(model => model.Image.FileName)%>
    <a href="#" onclick="jQuery('#imagedialog').dialog('open'); return false">Upload Image</a>
</div>

I have fileuploader.js and fileuploader.css linked properly on the master page, and the uploader appears correctly, and its even calling my action, but the HttpPostedFileBase is null and the upload action throws an exception. Any insight as to what I should do?

Edit

So I've figured out using firebug that its sending an XmlHttpRequest. How do I handle this in my upload action?

解决方案

The reason you are getting an empty parameter in your controller action is because this plugin doesn't send a multipart/form-data request to the server. Instead it sends application/octet-stream content type request header and it writes the file contents directly to the request stream, appending a parameter ?qqfile to the URL containing the file name. So if you want to retrieve this on the controller you will need to directly read the stream:

[HttpPost]
public ActionResult Upload(string qqfile)
{
    using (var reader = new BinaryReader(Request.InputStream))
    {
        // This will contain the uploaded file data and the qqfile the name
        byte[] file = reader.ReadBytes((int)Request.InputStream.Length);
    }
    return View();
}

If you select multiple files the plugin simply sends multiple requests to the server so this will work.

Also if you want to handle files bigger than int.MaxValue you will have to read from the request stream in chunks and write directly to an output stream instead of loading the whole file into a memory buffer:

using (var outputStream = File.Create(qqfile))
{
    const int chunkSize = 2 * 1024; // 2KB
    byte[] buffer = new byte[chunkSize];
    int bytesRead;
    while ((bytesRead = Request.InputStream.Read(buffer, 0, buffer.Length)) > 0)
    {
        outputStream.Write(buffer, 0, bytesRead);
    }
}

Remark: Remove the createUploader function name from your document.ready. It should be an anonymous function there. You could even merge it with the $(function() { ... }); you already have to setup the modal dialog.

这篇关于需要帮助调试XHR基础的Ajax图片上传与ASP.NET MVC2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆