我正在尝试使用jQuery插件Uploadify来处理ASP.NET MVC。
我已经使用以下JavaScript代码段显示了该插件:
<script type="text/javascript">
$(document).ready(function() {
$('#fileUpload').fileUpload({
'uploader': '/Content/Flash/uploader.swf',
'script': '/Placement/Upload',
'folder': '/uploads',
'multi': 'true',
'buttonText': 'Browse',
'displayData': 'speed',
'simUploadLimit': 2,
'cancelImg': '/Content/Images/cancel.png'
});
});
</script>
看起来一切都很顺利。如果您注意到,“script”属性设置为my / Placement / Upload,这是我的Placement Controller和我的上传操作。
主要问题是,我无法通过触发此操作来接收文件。我在该操作上设置了一个断点,当我选择要上传的文件时,它没有被执行。
我尝试根据this article更改方法签名:
public string Upload(HttpPostedFileBase FileData)
{
/*
*
* Do something with the FileData
*
*/
return "Upload OK!";
}
但这仍然不会发生。
任何人都可以帮我写并正确获取上传控制器操作的签名,这样它实际上会触发吗?然后我可以自己处理文件数据。我只是需要一些帮助才能解决方法操作。
答案 0 :(得分:20)
public string Upload(HttpPostedFileBase FileData) {}
是正确的 - uploadify上传的文件将被绑定到FileData。无需进入Request.Files来检索文件 - 这使得模拟和测试变得更加困难。
如果您的操作根本没有触发(即尝试调试并查看方法中的断点是否被命中),那么您的问题很可能就是“脚本”值 - 您是在虚拟目录下运行吗?如果是这样,您需要将目录的名称放在前面。 Uploadify使用绝对路径。
即。 'script:'/ virtual_directory / Placement / Upload'
现在uploadify正在发送到http://localhost/Placement/Upload。
还尝试使用路由调试器(http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx)来检查路由的映射位置。
答案 1 :(得分:10)
问题可能是您需要指定要上传到的操作设置为发布...它不能作为Get操作使用该操作。
所以,这个:
public string Upload(HttpPostedFileBase FileData)
{
//do something
}
应该是这样的:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Upload(HttpPostedFileBase FileData)
{
//do something
}
此外,请注意,如果您在网站的“已登录”部分中使用此功能,则应查看上传验证的已知错误:http://geekswithblogs.net/apopovsky/archive/2009/05/06/working-around-flash-cookie-bug-in-asp.net-mvc.aspx
另外,MVC可以通过多种方式处理文件上传(根据Rory Fitzpatrick的建议使用Request.Files,以及在操作定义中将HttpPostedFileBase文件作为参数传递)。为了让Uploadify起作用,这并不重要。
答案 2 :(得分:2)
这根本不是我实现文件上传的方式。我有一个没有参数的动作方法,它使用当前的Request对象潜入已发布文件的集合。
我的实施中的一些示例代码:
[AcceptVerbs(HttpVerbs.Post)]
public ContentResult Upload() {
if (Request.Files.Count > 0 && Request.Files[0].ContentLength > 0) {
HttpPostedFileBase postedFile = Request.Files[0];
// Do something with it
}
}
当然,为此编写测试成为PITA。您必须模拟几个对象才能使其工作,例如:
var mockHttpContext = mocks.StrictMock<HttpContextBase>();
var mockRequest = mocks.StrictMock<HttpRequestBase>();
var postedFile = mocks.StrictMock<HttpPostedFileBase>();
var postedFileKeyCollection = mocks.StrictMock<HttpFileCollectionBase>();
mockHttpContext.Expect(x => x.Request).Return(mockRequest).Repeat.Any();
mockRequest.Expect(x => x.Files).Return(postedFileKeyCollection).Repeat.Any();
postedFileKeyCollection.Expect(x => x[0]).Return(postedFile).Repeat.Any();
postedFileKeyCollection.Expect(x => x.Count).Return(1);
postedFile.Expect(f => f.ContentLength).Return(1024);
postedFile.Expect(f => f.InputStream).Return(null);
在发布的文件中创建一个接口会更容易,只有模拟它,并使用IoC将一个具体实现注入到控制器中。
我认为这很大程度上取决于这篇文章:Implementing HTTP File Upload with ASP.NET MVC including Tests and Mocks
答案 3 :(得分:2)
我对此的完整解决方案可能会解决您的问题。希望它有所帮助。
http://zootfroot.blogspot.com/2010/12/mvc-file-upload-using-uploadify-with.html
答案 4 :(得分:0)
阅读文档,看起来它正在发送一个文件数组。你试过了吗?
public string Upload( HttpPostedFileBase[] fileData )
默认模型绑定器也可能无法与HttpPostedFileBase一起使用,您可能需要使用Rory的机制或编写自己的模型绑定器。
答案 5 :(得分:0)
这是我简单的Razor View(布局大师有Javascript包)
@{
ViewBag.Title = "Upload Email CSV";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script type="text/javascript" src="@Url.Content("~/Scripts/Uploadify/jquery.uploadify.js")"></script>
<script type="text/javascript">
$(function () {
var uploadUrl = "@Url.Content("~/UploadFile/UploadEmailCSV/")";
var uploadSWF = "@Url.Content("~/Scripts/Uploadify/uploadify.swf")";
var uploadifyButtonImage = "@Url.Content("~/Scripts/Uploadify/uploadify.swf")";
$('#file_upload').uploadify({
'fileSizeLimit': '0',
'buttonImage': '/uploadify/browse-btn.png',
'swf': uploadSWF,
'uploader': uploadUrl,
'onUploadSuccess': function(file, data, response) {
alert('The file was saved to: ' + data);
}
});
});
</script>
<h2>Upload a comma separated list of email addresses</h2>
@using (Html.BeginForm("UploadEmailCSV", "UploadFile", FormMethod.Post, new { @class = "form-horizontal", @enctype = "multipart/form-data", @id = "frmUploadFiles" }))
{
<input type="file" name="file_upload" id="file_upload" />
}
这是控制器方法
public ActionResult UploadEmailCSV()
{
var uploadedFile = Request.Files["Filedata"];
if (uploadedFile != null && uploadedFile.ContentLength > 0)
{
var filePath = Path.Combine(Server.MapPath("~/UploadedFiles"), string.Format("{0}_{1}{2}", Path.GetFileNameWithoutExtension(uploadedFile.FileName), DateTime.Now.Ticks, Path.GetExtension(uploadedFile.FileName)));
uploadedFile.SaveAs(filePath);
return Content(string.Format("{0}_{1}{2}", Path.GetFileNameWithoutExtension(uploadedFile.FileName), DateTime.Now.Ticks, Path.GetExtension(uploadedFile.FileName)));
}
return Content("Error Uploading file!");
}
多数民众赞成!