2009-11-05 66 views
9

我正在使用JQuery表單插件在ASP.NET MVC應用程序上執行文件上載。我瞭解到,由於iframe用於文件上傳(而不是XMLHttpRequest,這是不可能的),所以服務器端對IsAjaxRequest的檢查失敗。使用ASP.NET MVC和JQuery表單插件/文件上傳檢測IsAjaxRequest()

我見過幾個與此問題相關的帖子,但還沒有遇到任何解決此問題的良好解決方案。與我的應用程序的其餘部分一樣,我希望能夠支持JavaScript啓用和禁用JavaScript的情況,這就是爲什麼我想要檢測請求是否是ajax。

我意識到使用的iframe方法在技術上並不是ajax,但我試圖模仿ajax效果。

任何建議將受到歡迎。

回答

9

我才意識到我完全沒有回答這個問題,所以我加入到頂部這裏,並在下方留下我的老回答:

的問題是在一個iFrame發佈的文件時,該「X-Requested-With」標題未設置,您無法爲Javascript中的常規表單POST設置特定的請求標頭。您必須訴諸其他技巧,例如發送包含值的POST的隱藏字段,然後更改或覆蓋「IsAjaxRequest」擴展方法以檢查此情況。 How to override an existing extension method?

也許是最好的選擇很可能會包括您自己的擴展方法有不同的名稱,基於了與修改默認的MVC擴展方法的代碼來檢測你的iFrame上傳帖子,然後任何地方使用您的擴展方法你期望需要它。


jQuery默認將'X-Requested-With'標頭設置爲'XMLHttpRequest'。只要您小心地通過jQuery執行所有AJAX調用,它就非常有用。

根據您的需求,可以很容易地安裝在動作過濾器檢測到使用需要的地方,甚至建立它變成一個控制器類,像這樣:

[jQueryPartial] 
public abstract class MyController : Controller 
{ 
    public bool IsAjaxRequest { get; set; } 
} 

的ActionFilterAttribute:

public class jQueryPartial : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     // Verify if a XMLHttpRequest is fired. 
     // This can be done by checking the X-Requested-With 
     // HTTP header. 
     MyController myController = filterContext.Controller as MyController; 
     if (myController != null) 
     { 
      if (filterContext.HttpContext.Request.Headers["X-Requested-With"] != null 
       && filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest") 
      { 
       myController.IsAjaxRequest = true; 
      } 
      else 
      { 
       myController.IsAjaxRequest = false; 
      } 
     } 
    } 
} 

並採用實現:

public class SomeController : MyController 
{ 
    public ActionResult Index() 
    { 
      if (IsAjaxRequest) 
       DoThis(); 
      else 
       DoThat(); 

      return View(); 
    } 
} 
+0

在你的代碼,IsAjaxRequest總是如此,擊敗了代碼的目的....再加上這是與擴展方法中存在的相同的功能......所以這真的不能幫助你。 – zowens 2009-11-06 00:32:58

+1

感謝您的信息。在您領導之後,我最終通過JQuery動態添加了一個隱藏表單值(「isFileUploadAjaxPost」)。在控制器中,我檢查該表單變量。如果它存在,我使用TempData存儲此值,然後調用RedirectToAction以顯示新上載文件的「編輯」視圖。在接收動作方法中,我檢查Request.IsAjaxRequest()(正如我一直在做的一樣)以及我的TempData值,以確定請求是否爲「ajax」。很棒。謝謝! – goombaloon 2009-11-06 03:49:40

+0

@zowens:我現在修復了這些代碼,但是,是的,我在實現它之後才意識到,然後查看完全相同的IsAjaxRequest擴展方法。我調整了ActionFilter中的代碼,該代碼根據請求類型動態設置母版頁,當然這比上面的代碼少一些冗餘。 – Jay 2009-11-06 07:16:44

11

您需要爲IsAjaxRequest方法設置「X-Requested-With」標頭以返回true。這是你如何在jQuery中做到這一點。

$(document).ready(function() { 
    jQuery.ajaxSetup({ 
      beforeSend: function (xhr) { 
       xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 
       return xhr; 
      } 
    }); 
}); 
+0

JQuery表單插件不使用XMLHttpRequest進行文件上傳。它使用一個iframe。 – goombaloon 2009-11-05 20:52:06

+0

這將是完美的答案,如果它的工作... – 2013-12-12 22:57:04

+1

在角''httpProvider.defaults.headers.common = {'X-Requested-With':'XMLHttpRequest'};' – parliament 2014-06-29 19:16:03

2

我只是偶然ACR oss這個問題,後來發現更好的解決方案,所以在這裏(對於從谷歌得到這裏的每個人):

jQuery表單插件有兩個選項,可能有助於在這種情況下。

  1. 如果你正在使用POST請求,它似乎總是使用iframe的,所以如果你不需要的文件上傳,設置IFRAME =在窗體選項虛假幫助我的情況。

  2. 如果你需要文件上傳的iframe,您可以使用的選項數據屬性有兩個選項來糊弄

    IsAjaxRequest() setting : data: { "X-Requested-With": "XMLHttpRequest" }

完整的腳本看起來像這樣:

$('#someform').ajaxForm(
{ 
     dataType: 'json', 
     success: onSuccess, 
     error: onError, 
       iframe: false 
     data: { "X-Requested-With": "XMLHttpRequest" } 
    } 
); 
11

從ASP.NET MVC 2(及之後)開始,在Request上有一個擴展方法。

if (Request.IsAjaxRequest()) 
{ 
    // was an ajax request 
} 

上的控制器方法使用一個jQuery方法如.load()將導致Request.IsAjaxRequest()返回true。

相關問題