【问题标题】:Ajax upload script for multiple files, jQuery ASP.NET MVC用于多个文件的 Ajax 上传脚本,jQuery ASP.NET MVC
【发布时间】:2011-09-18 14:36:15
【问题描述】:

我正在为 ASP.NET MVC 应用程序编写上传脚本。我有一个适用于一个文件的实现,但我想扩展它以处理多个上传。这是原始实现:

上传视图(是的,我将把这个 jQuery 代码移到它自己的文件中):

<script type="text/javascript">
    var fieldCount = 0;
    function addField() {
        var name = 'file' + fieldCount;
        var row = 'row' + fieldCount;
        var str = '<p id="' + row + '"><label for="' + name + '">File to upload: <input type="file" name="' + name + '" id="' + name + '" />(100MB max size) <a onclick="removeRow(\'#' + row +     '\'); return false;">[-]</a></label></p>';
        fieldCount++;
        $("#fields").append(str);
    };
    function removeRow(id) {
        if ($("#fields").children().size() > 1) {
            $(id).remove();
        }
    };
    $(function() {
        $("#ajaxUploadForm").ajaxForm({
            iframe: true,
            dataType: "json",
            beforeSubmit: function() {
                $("#resultBox").show();
                $("#status").html('<h1><img src="/Content/busy.gif" /> Uploading file...</h1>');
            },
            success: function(result) {
                $("#ajaxUploadForm").unblock();
                $("#ajaxUploadForm").resetForm();
                var tcolor;
                var msg;
                if (!result.message) {
                    tcolor = "red";
                    msg = result.error;
                }
                else {
                    tcolor = "green";
                    msg = result.message;
                }
                $("#resultBox").show();
                $("#status").html('<span style="color:' + tcolor + ';">' + msg + '</span>').animate({ opacity: 1.0 }, 3000).fadeOut('slow', function() {
                    $("#resultBox").hide();
                });
            },
            error: function(xhr, textStatus, errorThrown) {
                $("#ajaxUploadForm").unblock();
                $("#ajaxUploadForm").resetForm();
                $("#resultBox").add("p").attr("id", "status").css("margin-top", "15px").css("padding", "20px");
                $("#status").html('<span style="color:red;">Error uploading file</span>').animate({ opacity: 1.0 }, 3000).fadeOut('slow', function() {
                    $("#resultBox").hide();
                });
            }
        });
    });
</script>
<form id="ajaxUploadForm" action="<%= Url.Action("AjaxUpload", "Upload")%>" method="post" enctype="multipart/form-data">
    <fieldset id="uploadFields">
        <legend>Upload a file</legend>
        <div id="fields"></div>
        <input id="ajaxUploadButton" type="submit" value="Submit" />            
    </fieldset>
    <a onclick="addField(); return false;" id="add">Add</a>
    <div id="resultBox">
        <p id="status" style="margin:10px;"></p>
    </div>
</form> 

动作结果:

public FileUploadJsonResult AjaxUpload(HttpPostedFileBase file)
{
    Upload fileToUpload;
    try
    {
        fileToUpload = new Upload
        {
            filename = file.FileName,
            filesize = file.ContentLength,
            date = DateTime.Now,
            id = Guid.NewGuid()
        };

    var savedFileName = Server.MapPath(Path.Combine(@"~/uploads", Path.GetFileName(fileToUpload.filename)));
    if (System.IO.File.Exists(savedFileName))
    {
        throw new Exception(string.Format("The file '{0}' already exists on the server.", file.FileName));
    }
    file.SaveAs(savedFileName);
    }
    catch (Exception ex)
    {
        return new FileUploadJsonResult { Data = new { error = string.Format("Upload failure: {0}", ex.Message), message = string.Empty } };
    }
    return new FileUploadJsonResult { Data = new { message = string.Format("{0} uploaded successfully. (id:{1})", Path.GetFileName(file.FileName), fileToUpload.id) } };
}

我使用概念 from this blog post 来推动这一切。


现在使用我的 javascript 添加/删除字段,我稍微更改了操作结果:

public List<FileUploadJsonResult> AjaxUpload(HttpPostedFileBase fileBase)
{
    var results = new List<FileUploadJsonResult>();
    try
    {
        if (Request.Files.Count > 0)
        {
            Upload uploadFile;
            for (var i = 0; i <= (Request.Files.Count - 1); i++)
            {
                HttpPostedFileBase file = Request.Files[i];
                uploadFile = new Upload
                {
                    filename = file.FileName,
                    filesize = file.ContentLength,
                    date = DateTime.Now,
                    id = Guid.NewGuid()
                };
                var savedFileName = Server.MapPath(Path.Combine(@"~/uploads", Path.GetFileName(uploadFile.filename)));
                if (System.IO.File.Exists(savedFileName))
                {
                    results.Add(new FileUploadJsonResult { Data = new { error = string.Format("Upload failure: {0}", string.Format("The file '{0}' already exists on the server.", file.FileName)), message = string.Empty } });
                }
                file.SaveAs(savedFileName);
                results.Add(new FileUploadJsonResult { Data = new { message = string.Format("{0} uploaded successfully", file.FileName) } });
            }
        }
    }
    catch (Exception ex)
    {
        results.Add(new FileUploadJsonResult { Data = new { error = string.Format("Upload failure: {0}", ex.Message), message = string.Empty } });
    }
    return results;
}

我有点卡在这一点上。上传工作正常,但我的 javascript 出错了,因为我返回的是一个列表而不是单个项目。我想如果我调整那部分代码以遍历结果列表,这是可以完成的。

我想做的另一件事是在每个文件完成上传后,将成功文本添加到结果框。

任何帮助将不胜感激!谢谢!

【问题讨论】:

    标签: jquery asp.net-mvc


    【解决方案1】:

    您好,您必须在这里返回一个 ActionResult,您不能返回它们的列表。 您还使用 Request.Files 集合,因此您无需在操作中使用 HttpPostedFileBase fileBase。

    这样的事情可能对你有用

        public FileUploadJsonResult AjaxUpload() {
            try {
                foreach (string name in Request.Files) {
                    var file = Request.Files[name];
                    if (!string.IsNullOrEmpty(file.FileName)) {
                        file.SaveAs( Server.MapPath(Path.Combine(@"~/uploads", Path.GetFileName(file.FileName)));
                    }
                }
            } catch (Exception ex) {
                return new FileUploadJsonResult {
                    Data = new {
                        error = string.Format("Upload failure: {0}", ex.Message),
                        message = string.Empty
                    }
                };
            }
    
            return new FileUploadJsonResult { 
                Data = new { 
                    message = "file(s) uploaded successfully"
                }
            };
        }
    

    另外,您可能想要一个HttpModule to provide a progress bar 该示例使用 jQuery.form 插件和 jquery ui 进度条

    【讨论】:

    • 为了使我的脚本能够正常工作,我必须将 HttpPostedFileBase 作为参数。在原始实现中,您将看到代码中使用了参数。在多文件实现中,我改用 Request.Files 来处理每个文件。
    • 嗨 Anders,我看到它在您的原始实现中使用,但在您的多文件实现中没有使用。您可以更改您的 js 以分别加载每个文件并使用原始实现...?
    • 我不完全确定如何按照您的建议去做。据我所知,javascript 只处理提交表单并将表单数据转储到隐藏的 iframe 中,以便可以异步提交表单。我对 js 有点生疏了,我才刚刚开始重新投入工作。有什么建议或我可以尝试的吗?谢谢!
    猜你喜欢
    • 2011-01-26
    • 1970-01-01
    • 2013-01-28
    • 2020-12-25
    • 2011-02-07
    • 2021-12-10
    • 2021-03-21
    相关资源
    最近更新 更多