35

我正在尝试让 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>

看起来一切都很好。如果您注意到,“脚本”属性设置为我的 /Placement/Upload,这是我的放置控制器和我的上传操作。

主要问题是,我很难让这个动作触发来接收文件。我已经在该操作上设置了一个断点,当我选择要上传的文件时,它没有被执行。

我已经尝试根据这篇文章更改方法签名:

public string Upload(HttpPostedFileBase FileData)
{
    /*
    *
    * Do something with the FileData
    *
    */
    return "Upload OK!";
}

但这仍然没有触发。

谁能帮我正确编写并获取上传控制器操作的签名,以便它真正触发?然后我可以自己处理文件数据。我只需要一些帮助来触发方法操作。

4

6 回答 6

20
public string Upload(HttpPostedFileBase FileData) {}

是正确的——uploadify 上传的文件将绑定到 FileData。无需进入 Request.Files 来检索文件——这使得模拟和测试变得更加困难。

如果您的操作根本没有触发(即尝试调试并查看方法中的断点是否被命中),那么您的问题很可能是“脚本”值 - 您是否在虚拟目录下运行?如果是这样,您需要将目录的名称放在前面。Uploadify 使用的是绝对路径。

即'脚本:'/virtual_directory/Placement/Upload'

现在 uploadify 正在发送到http://localhost/Placement/Upload

还可以尝试使用路由调试器(http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx)来检查您的路由映射到的位置。

于 2009-08-21T01:22:43.630 回答
10

问题可能是您需要指定您要上传到的操作设置为发布...它不能将该操作用作获取操作。

所以这:

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 正常工作,这并不重要。

于 2009-07-15T08:37:46.140 回答
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

于 2009-06-16T17:01:56.587 回答
2

我对此的完整解决方案可能会解决您的问题。希望能帮助到你。

http://zootfroot.blogspot.com/2010/12/mvc-file-upload-using-uploadify-with.html

于 2010-12-06T22:19:06.417 回答
0

阅读文档,看起来它正在发送一个文件数组。你有没有尝试过:

public string Upload( HttpPostedFileBase[] fileData )

默认模型绑定器也可能无法与 HttpPostedFileBase 一起使用,您需要使用 Rory 的机制或编写自己的模型绑定器。

于 2009-06-16T17:04:45.943 回答
0

这是我的简单 Razor 视图(布局大师有 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!");
    }

就是这样!

于 2013-09-06T21:48:40.747 回答