使用局部视图在jQuery对话框中上载文件

Ste*_*ven 2 c# asp.net asp.net-mvc asp.net-mvc-3

我有一个页面,您可以在其中编辑客户端.在此页面上,您还可以上载客户端的文件.单击按钮,打开jQuery对话框,上载文件,然后单击"保存".

这是我的/客户/编辑视图:

<script type="text/javascript" language="javascript">

    $(document).ready(function () {

        // add file click event
        $("a#addFile").click(function () {
            $.ajax({
                url: '@Url.Content("/ClientFiles/Create/")' + @Model.ClientId,
                context: document.body,
                success: function (data) {
                    // open dialog with Create partial view data
                    $("#dialog-add").html(data).dialog("open");
                }
            });

            return false;
        });


        // add file dialog settings
        $("#dialog-add").dialog({
            modal: true,
            buttons: {
                "Save": function () {
                    $.validator.unobtrusive.parse("#AddFileForm");
                    if ($("#AddFileForm").valid()) {
                        $.post("/ClientFiles/Create", $("#AddFileForm").serialize(),
                            function (data) {
                                $("#dialog-add").dialog("close");   // close dialog
                            });
                    }
                }
            }
        });
    });

</script>

@using (Html.BeginForm("Edit", "Clients", FormMethod.Post))
{
    @Html.HiddenFor(m => m.ClientId)            

    <a id="addFile">Add a new file</a>
    <div id="dialog-add" title="" style="display:none"></div>        

    <input type="submit" value="Save" />            
}
Run Code Online (Sandbox Code Playgroud)

这是我的/ ClientFiles/Create局部视图:

@model Models.ClientFileViewModel

@using (Html.BeginForm("Create", "ClientFiles", FormMethod.Post, new { @id = "AddFileForm", enctype = "multipart/form-data" }))
{
    @Html.ValidationSummary(true)

    @Html.HiddenFor(model => model.ClientId)    
    @Html.TextBoxFor(model => model.ModelFile, new { type = "file" })

    @Html.ValidationSummary()
}
Run Code Online (Sandbox Code Playgroud)

这是我的ClientFileViewModel:

public class ClientFileViewModel
{
    [ScaffoldColumn(false)]
    public int ClientFileId { get; set; }

    public int ClientId { get; set; }
    public HttpPostedFile ModelFile { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

最后,我的ClientFilesController方法:

public ActionResult Create(int id)
{
    return PartialView(new ClientFileViewModel { ClientId = id  } );
}

public JsonResult Create(ClientFileViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        if (viewModel.ModelFile != null)
        {
            // upload file here
        }
    }

    return Json(new { success = true });
}
Run Code Online (Sandbox Code Playgroud)

所以一切顺利,直到我发布到Create(ClientFileViewModel viewModel).当我浏览调试器时,视图模型包含ClientId但是ModelFile为null.

我做错了导致文件无法与视图模型一起传递吗?

Dar*_*rov 5

你应该使用基类(HttpPostedFileBase),即替换:

public HttpPostedFile ModelFile { get; set; }
Run Code Online (Sandbox Code Playgroud)

有:

public HttpPostedFileBase ModelFile { get; set; }
Run Code Online (Sandbox Code Playgroud)

在您的视图模型中.


话虽这么说,这只是你问题的一半.您似乎使用AJAX请求提交表单:

$.post("/ClientFiles/Create", $("#AddFileForm").serialize(),
Run Code Online (Sandbox Code Playgroud)

您无法使用AJAX将文件上载到服务器.您可以使用一些插件,例如jquery.form,它支持文件输入字段并生成隐藏的iframe以规避此限制.因此,如果您决定使用该插件,您可以执行以下操作来进行AJAXify:

"Save": function () {
    $.validator.unobtrusive.parse("#AddFileForm");
    if ($("#AddFileForm").valid()) {
        $("#AddFileForm").ajaxSubmit(function() {
            $("#dialog-add").dialog("close");
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

其他可以上传文件的流行插件有Uploadify,Blueimp文件上传,Ajax上传,......