2011-11-17 43 views
0

我從下面的URL的一個例子,展示瞭如何使用jQuery表單插件來做一個異步文件上傳到我的.NET MVC控制器。 (http://aspzone.com/tech/jquery-file-upload-in-asp-net-mvc-without-using-flash/)第一次,我第一次上傳文件後,所有工作都非常好,我第一次更換了表單所在的div,通過返回的PartialView。當div被替換後,我再調用一個javascript函數來重建ajaxForm對象,但似乎是停止工作的地方。當代碼返回第一次我得到我的替換的div就好了,外觀是適當的,但JavaScript代碼似乎並沒有將ajaxForm對象附加到替換的div內存在的窗體。這意味着我第二次發佈表單時,它會將用戶從頁面中重定向。我很想說這是控制器中的緩存問題,但我得到的響應顯示了ascx中更新的項目列表。最後一件事,當我查看IE開發工具欄中的dom元素時,我看到一個像「jQuery16404440065521567182」這樣的屬性,其值爲33,並且在第一次提交後消失。我猜這是由ajaxForm放在那裏。下面是我使用(一些JavaScript的命名空間的改變,除去特定項目的命名)的代碼:jQuery ajax表單文件上傳到.Net MVC與InsertionMode.Replace只能工作一次

ASCX文件

<!-- Form to add a new record --> 
<% using (Html.BeginForm("SaveAttachment", "Report", FormMethod.Post, new { enctype = "multipart/form-data", id = "AttachmentForm" })) { %> 
<input type="hidden" name="ReportId" value="<%: Model.ReportId %>" /> 
<input type="file" name="FileUpload" value="" size="21" /> 
<label for="Title"> 
    Title:</label> 
<input type="text" name="Title" value="" /> 
<input type="submit" value="Add" class="inputButton" /> 
<% } %> 

<!-- Display existing items --> 
    <% foreach (var item in Model.ExistingAttachments) { %> 
<div> 
    <%: item.Sort %>&nbsp;<%: item.Title.PadRight(25, ' ').Substring(0, 25).TrimEnd() %></div> 
<% } %> 

ASPX文件

<div id="AttachmentsWindow"> 
    <% Html.RenderPartial("LoadAttachments", Model.ReportAttachments); %> 
</div> 

<!-- This form is used to refresh the above div --> 
<% using (Ajax.BeginForm("LoadAttachments", new { ReportId = Model.ReportId }, 
      new AjaxOptions { 
       HttpMethod = "Post", 
       LoadingElementId = "LoadingAttachments", 
       UpdateTargetId = "AttachmentsWindow", 
       InsertionMode = InsertionMode.Replace, 
       OnComplete = "Report.InitAttachment" 
      }, new { id = "LoadAttachmentsForm" })) { %> 
    <input type="submit" name="submit" value="" class="button" style="float:right;" 
    onmouseover="this.className='button buttonhov'" onmouseout="this.className='button'"/> 
    <% } %> 

控制器

[HttpPost] 
    [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")] 
    public FileUploadJsonResult SaveAttachment(ReportAttachmentViewModel Attachment) { 

     if (Attachment.FileUpload.ContentLength < 1){ 
      return new FileUploadJsonResult { Data = new { message = "No file chosen." } }; 
     } 

     var Report = this._reportRepository.GetById(Attachment.ReportId); 

     if (Report == null) 
      throw new Exception("Report not found"); 


     MemoryStream target = new MemoryStream(); 
     Attachment.FileUpload.InputStream.CopyTo(target); 
     byte[] data = target.ToArray(); 


     ReportAttachment newobj = new ReportAttachment { 
      Attachment = data, 
      Description = string.Empty, 
      Name = Attachment.Title, 
      Report = Report, 
      ReportId = Report.Id 
     }; 

     var result = this._reportAttachmentRepository.Add(ref newobj); 

     Report.ReportAttachments.Add(newobj); 

     ModelState.Clear(); 

     if (!result.Success) { 

      StringBuilder sb = new StringBuilder(); 

      foreach (var msg in result.Messages) { 
       sb.AppendLine(string.Format("{0}", msg.Message)); 
      } 

      return new FileUploadJsonResult { Data = new { message = sb.ToString() } }; 
     }    

     return new FileUploadJsonResult { Data = new { message = string.Format("{0} uploaded successfully.", System.IO.Path.GetFileName(Attachment.FileUpload.FileName)) } }; 

Javascript

//Report namespace 
InitAttachment: function() { 
     jQuery('#AttachmentForm').ajaxForm({ 
     iframe: true, 
     dataType: "json", 
     beforeSubmit: function() { 
      jQuery('#AttachmentForm').block({ message: 'Uploading File... ' }); 
     }, 
     success: function (result) { 
      jQuery('#AttachmentForm').unblock(); 
      jQuery('#AttachmentForm').resetForm(); 
      $.growlUI(null, result.message); 

      Editor.EndLoading(false, false, true); 
     }, 

     error: function (xhr, textStatus, errorThrown) { 
      $("#ajaxUploadForm").unblock(); 
      $("#ajaxUploadForm").resetForm(); 
      $.growlUI(null, 'Error uploading file'); 
     } 
    }); 

//Editor namespace 
EndLoading: function (ReloadReportSections, ReloadReferences, ReloadAttachments) { 

    //Reload sections 
    if (ReloadReportSections) 
     jQuery('#LoadReportSectionsForm').submit(); 

    if (ReloadReferences) 
     jQuery('#LoadReferencesForm').submit(); 

    if (ReloadAttachments) { 
     jQuery('#LoadAttachmentsForm').submit(); 
    } 
    //endReload 


    Report.InitAttachment(); 

    //Close the loading dialog 
    jQuery('#LoadingWindow').dialog('close'); 
} 

回答

0

事實證明,這是我在錯誤的位置調用更新。在我看來,我會想像會在OnComplete之前觸發,但在MS Ajax模型中它不會。我們調用了OnSuccess,它看起來好像影響了代碼,因爲它已經達到了我設置的所有斷點,但在調用Replace邏輯之前它一定是擊中了舊的DOM元素。我似乎無法找到任何有關這種情況發生順序的文檔,但我注意到,當我從AjaxOptions.OnSuccess屬性中調用.ajaxForm時,一切正常。所以我的建議總之:

使用AjaxOptions.OnSuccessAjaxOptions.OnFailed影響更新的DOM,但如果您需要臨時邏輯AjaxOptions.OnComplete

0

在致電ajaxForm()之前,您可能需要刪除隱藏的iframe(如果存在)InitAttachment()。 聽起來像文件上傳表單的目標可能會變得混亂,如果以前上傳的iframe仍然存在。 我已經與ExtJS中的類似問題爭鬥過,不能說它是相同的。