2009-11-05 9 views
9

Utilizzo il plug-in JQuery Form per eseguire un caricamento di file su un'applicazione ASP.NET MVC. Ho imparato che poiché un iframe viene utilizzato per i caricamenti di file (piuttosto che XMLHttpRequest, che non è possibile), il controllo sul lato server per IsAjaxRequest ha esito negativo.Rilevamento di IsAjaxRequest() con ASP.NET MVC e caricamento di file/plug-in JQuery Form

Ho visto alcuni post relativi a questa domanda ma non ho trovato nessuna soluzione valida per ovviare a questo problema. Come con il resto della mia applicazione, mi piacerebbe essere in grado di supportare sia JavaScript abilitato e JavaScript disattivato scenari, che è il motivo per cui vorrei rilevare se una richiesta è ajax o meno.

Mi rendo conto che l'approccio iframe utilizzato non è tecnicamente ajax, ma sto cercando di imitare un effetto Ajax.

Qualsiasi suggerimento sarebbe benvenuto.

risposta

9

Ho appena realizzato che assolutamente non ha risposto alla domanda, quindi sto aggiungendo alla parte superiore qui, e lasciando il mio vecchio risposta qui sotto:

Il problema è quando la pubblicazione di un file su un iFrame, il L'intestazione "X-Requested-With" non è impostata e non è possibile impostare intestazioni di richiesta specifiche per un POST di formato normale in Javascript. Dovrai ricorrere ad altri trucchi, ad esempio inviare un campo nascosto con il tuo POST che contiene un valore, quindi modificare o sovrascrivere il metodo di estensione "IsAjaxRequest" per verificare anche questa condizione. How to override an existing extension method?

probabilmente l'opzione migliore sarebbe probabilmente per inserire il tuo metodo di estensione con un nome diverso, in base al largo il MVC codice di metodo di estensione di default con i cambiamenti di rilevare l'iFrame caricare POST, e quindi utilizzare il metodo di estensione ovunque ti aspetti di averne bisogno.


jQuery imposta effettivamente l'intestazione 'X-Requested-With' su 'XMLHttpRequest' per impostazione predefinita. È abbastanza utile se fai attenzione a fare tutte le tue chiamate AJAX su jQuery.

A seconda delle esigenze, è facile da installare il rilevamento in un filtro di azione per usarla dove necessario, o addirittura costruire in una classe di controllo in questo modo:

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

L'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; 
      } 
     } 
    } 
} 

E usando l'implementazione:

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

      return View(); 
    } 
} 
+0

Nel tuo codice , IsAjaxRequest è sempre true, vanificando lo scopo del codice .... in più è la stessa funzionalità che esiste nel metodo di estensione ... quindi non ti aiuta davvero. – zowens

+1

Grazie per l'informazione. Seguendo la tua guida, ho finito per aggiungere in modo dinamico un valore di modulo nascosto ("isFileUploadAjaxPost") tramite JQuery. Nel controller, controllo la variabile del modulo. Se è presente, utilizzo TempData per memorizzare questo valore prima di chiamare RedirectToAction per visualizzare la vista "modifica" per il file appena caricato. Nel metodo di azione di ricezione, controllo sia Request.IsAjaxRequest() (come ho fatto fin dall'inizio) sia il mio valore di TempData per determinare se la richiesta è "ajax" o meno. Funziona alla grande. Grazie! – goombaloon

+0

@zowens: Ho corretto il codice ora, ma sì, mi sono reso conto dopo averlo fatto e poi guardando il metodo di estensione IsAjaxRequest che è esattamente lo stesso. Ho adattato il codice da un ActionFilter che imposta dinamicamente la pagina master in base al tipo di richiesta che, ovviamente, è un po 'meno ridondante del codice precedente. – Jay

11

È necessario impostare l'intestazione "X-Requested-With" per il metodo IsAjaxRequest per restituire true. Ecco come lo fai in jquery.

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

Il plug-in Modulo JQuery non utilizza XMLHttpRequest per i caricamenti di file. Usa un iframe. – goombaloon

+0

Questa sarebbe stata la risposta perfetta, se ha funzionato ... –

+1

ha funzionato per me in angolare '$ httpProvider.defaults.headers.common = {'X-Requested-With': 'XMLHttpRequest'};' – parliament

2

ho appena imbattuto acr oss questa domanda e in seguito trovato una soluzione migliore, quindi eccolo (per tutti quelli che arrivano da google):

Il plug in modulo jQuery ha due opzioni che potrebbero aiutare in questo caso.

  1. se si utilizza richiesta post, sembra che sia sempre utilizza l'iframe, quindi se non avete bisogno di upload di file, impostando iframe = false nelle opzioni modulo aiutato nel mio caso.

  2. Se avete bisogno di iframe per fileuploads, è possibile utilizzare la proprietà dei dati delle opzioni per ingannare la sceneggiatura completa

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

con entrambe le opzioni si presenta così:

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

A partire da ASP.NET MVC 2 (e successivi) è disponibile un metodo di estensione su Request.

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

Utilizzando un metodo jQuery come .load() su un metodo di controllo si tradurrà in Request.IsAjaxRequest() restituendo vero.

Problemi correlati