使用MVC从标准Html表单回发部分视图

时间:2010-06-15 14:09:43

标签: jquery asp.net-mvc ajax jquery-plugins partial-views

我的MVC视图上有一个文件上传按钮。上传文件后,页面上的FileList部分视图应该刷新。

我尝试使用Ajax.BeginForm()上传,但发现Ajax不会提交文件数据。

我现在使用jQuery Form plugin让文件上传正常工作,这样可以让您正常Html.BeginForm()提交方法。

是否仍然可以使用此方法触发部分页面更新?

2 个答案:

答案 0 :(得分:3)

是的,您可以使用.ajaxForm中的成功选项从文件上传传回数据,然后将该数据传递给PartialView或只刷新部分。

     // Setup the from plugin
    $('#formId').ajaxForm(
                          success: function(data) { UploadSuccess(data); },
                          dataType: 'json', 
                          iframe:true);
    $('#formId').submit();

    // Success callback fundtion
    function UploadSuccess(data)
    {
        // You can then access any data in the JSON object and pass it in the route to the partial
        $('#divId').load('/FileList/' + data.FileName);
    }

// Original HTML of partial
<div id="divId">
    <%Html.RenderPartial("FileList");%>
</div>

        // Action to handle upload
        public FileUploadJSONResult Upload()
        {
            FileUploadJSONResult result;

            try
            {
                if (Request.Files.Count > 0)
                {
                    //  Logic to save file goes here

                    result = new FileUploadJSONResult()
                    {
                        Data = new
                        {
                            FileName = "Test filename",
                            ErrorMessage = string.Empty
                        }
                    };
                }
                else
                {
                    result = new FileUploadJSONResult
                    {
                        Data = new
                        {
                            FileName = string.Empty,
                            LogicalName = string.Empty,
                            ErrorMessage = "No file to upload. Please select a file to upload."
                        }
                    };
                }
            }
            catch (Exception e)
            {
                Exception root = e;
                while ((root.InnerException) != null)
                {
                    root = root.InnerException;
                }

                result = new FileUploadJSONResult
                {
                    Data = new
                    {
                        FileName = string.Empty,
                        LogicalName = string.Empty,
                        ErrorMessage = root.Message
                    }
                };
            }

            return result;
        }

// Then needed to wrap the JSON result due to the iframe textarea issue with this plugin
public class FileUploadJSONResult : JsonResult
    {  
        /// <summary>
        /// The following explanation of this code is from http://www.malsup.com/jquery/form:
        /// 
        ///  Since it is not possible to upload files using the browser's XMLHttpRequest object, the Form Plugin 
        ///  uses a hidden iframe element to help with the task. This is a common technique, but it has inherent limitations. 
        ///  The iframe element is used as the target of the form's submit operation which means that the server response is 
        ///  written to the iframe. This is fine if the response type is HTML or XML, but doesn't work as well if the 
        ///  response type is script or JSON, both of which often contain characters that need to be repesented using 
        ///  entity references when found in HTML markup.
        ///  To account for the challenges of script and JSON responses, the Form Plugin allows these responses to be 
        ///  embedded in a textarea element and it is recommended that you do so for these response types when used in 
        ///  conjuction with file uploads. Please note, however, that if a file has not been selected by the user for the 
        ///  file input then the request uses normal XHR to submit the form (not an iframe). This puts the burden on your 
        ///  server code to know when to use a textarea and when not to. If you like, you can use the iframe option of the 
        ///  plugin to force it to always use an iframe mode and then your server can always embed the response in a textarea. 
        /// </summary>
        /// <param name="context">Controller context</param>
        public override void ExecuteResult(ControllerContext context)
        {
            this.ContentType = "text/html";
            context.HttpContext.Response.Write("<textarea>");
            base.ExecuteResult(context);
            context.HttpContext.Response.Write("</textarea>");
        }
    }

答案 1 :(得分:2)

如果我正确理解您的问题,您应该能够为jQuery Form插件的success属性提供回调函数(请查看此链接以获取所有选项:http://jquery.malsup.com/form/#options-object )。

然后在该javascript函数中,您可以对FileList部分视图进行任何更新,您需要...是GET请求更新部分视图,还是只捕获responseText来自jQuery Form插件的成功回调函数。