Частичная обратная передача просмотра из стандартной HTML-формы с MVC

У меня есть кнопка загрузки файла в моем представлении MVC. После загрузки файла мой FileList частичный вид на странице должен обновиться.

Я пытался загрузить с помощью Ajax.BeginForm(), но обнаружил, что Ajax не отправляет данные файла.

Теперь у меня работает загрузка файлов с помощью плагина jQuery Form, который позволяет вам ajaxify обычный метод отправки Html.BeginForm().

Можно ли по-прежнему запускать частичное обновление страницы с помощью этого метода?


person fearofawhackplanet    schedule 15.06.2010    source источник


Ответы (2)


Да, вы можете использовать параметр успеха в .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>");
        }
    }
person amurra    schedule 15.06.2010
comment
Спасибо, ваш ответ направил меня в правильном направлении. Хотя на самом деле это намного проще, так как я могу напрямую вернуть html из частичного представления вместо возврата объекта данных json. - person fearofawhackplanet; 16.06.2010

Если я правильно понимаю ваш вопрос, вы должны предоставить функцию обратного вызова для свойства success плагина формы jQuery (ознакомьтесь со всеми параметрами по этой ссылке: http://jquery.malsup.com/form/#options-object).

Затем внутри этой функции javascript вы можете делать любые обновления частичного представления FileList, которые вам нужны... будь то запрос GET на обновление частичного представления или просто захват responseText из функции обратного вызова успеха плагина формы jQuery.

person mkchandler    schedule 15.06.2010