需要帮助使用 ASP.NET MVC2 调试基于 XHR 的 Ajax 图像上传
我正在尝试使用 http://valums.com/ajax-upload/ 中找到的脚本
我的控制器如下
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());
}
}
}
我有一个像这样的部分视图
<%@ 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>
我在母版页上正确链接了 fileuploader.js 和 fileuploader.css,上传器显示正确,甚至调用我的操作,但 HttpPostedFileBase 为空并且上传操作抛出异常。关于我应该做什么有什么见解吗?
编辑
所以我发现使用 firebug 发送 XmlHttpRequest。我该如何在上传操作中处理这个问题?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您在控制器操作中获得空参数的原因是因为此插件不会向服务器发送
multipart/form-data
请求。相反,它发送application/octet-stream
内容类型请求标头,并将文件内容直接写入请求流,并将参数?qqfile
附加到包含文件名的 URL 。因此,如果您想在控制器上检索此内容,您将需要直接读取流:如果您选择多个文件,则插件只需向服务器发送多个请求,这样就可以工作。
此外,如果您想处理大于 int.MaxValue 的文件,您将必须从请求流中读取块并直接写入输出流,而不是将整个文件加载到内存缓冲区中:
备注:从
document.ready
中删除createUploader
函数名称。那里应该是一个匿名函数。您甚至可以将其与您已经必须设置模式对话框的$(function() { ... }); 合并。
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 sendsapplication/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: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:Remark: Remove the
createUploader
function name from yourdocument.ready
. It should be an anonymous function there. You could even merge it with the$(function() { ... });
you already have to setup the modal dialog.