2009-11-05 2 views
9

J'utilise le plugin JQuery Form pour effectuer un téléchargement de fichier sur une application ASP.NET MVC. J'ai appris que, comme un iframe est utilisé pour les téléchargements de fichiers (plutôt que XMLHttpRequest, ce qui n'est pas possible), la vérification côté serveur de IsAjaxRequest échoue.Détection de IsAjaxRequest() avec ASP.NET MVC et téléchargement de plugin/fichier de formulaire JQuery

J'ai vu quelques articles liés à cette question, mais je n'ai pas trouvé de bonnes solutions pour contourner ce problème. Comme pour le reste de mon application, j'aimerais pouvoir prendre en charge les scénarios JavaScript et JavaScript désactivés, c'est pourquoi je souhaite détecter si une requête est ajax ou non.

Je me rends compte que l'approche iframe utilisée n'est pas techniquement ajax, mais j'essaye d'imiter un effet ajax.

Toutes les suggestions seraient les bienvenues.

Répondre

9

Je ne viens de réaliser que je totalement pas répondre à la question, donc je suis d'ajouter au sommet ici, et en laissant ma vieille réponse ci-dessous:

Le problème est lors de la publication d'un fichier sur un iFrame, le L'en-tête "X-Requested-With" n'est pas défini et vous ne pouvez pas définir d'en-têtes de requête spécifiques pour un formulaire normal POST en Javascript. Vous devrez recourir à d'autres astuces, comme l'envoi d'un champ caché avec votre POST qui contient une valeur, puis modifier ou remplacer la méthode d'extension "IsAjaxRequest" pour vérifier également cette condition. How to override an existing extension method?

Probablement la meilleure option serait probablement d'inclure votre propre méthode d'extension avec un nom différent, basé sur l'code de la méthode d'extension par défaut MVC avec les modifications pour détecter votre iFrame opération POST, puis utilisez votre méthode d'extension partout où vous vous attendez à en avoir besoin.


jQuery définit en fait l'en-tête 'X-Requested-With' à 'XMLHttpRequest' par défaut. C'est très utile tant que vous faites attention à tous vos appels AJAX via jQuery.

En fonction de vos besoins, il est facile de configurer la détection dans un filtre d'action pour l'utiliser en cas de besoin, ou même construire dans une classe de contrôleur comme ceci:

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

Le 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; 
      } 
     } 
    } 
} 

Et en utilisant la mise en œuvre:

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

      return View(); 
    } 
} 
+0

Dans votre code , IsAjaxRequest est toujours vrai, en vainant le but du code .... plus c'est la même fonctionnalité qui existe dans la méthode d'extension ... donc cela ne vous aide vraiment pas. – zowens

+1

Merci pour l'information. En suivant votre exemple, j'ai fini par ajouter dynamiquement une valeur de formulaire cachée ("isFileUploadAjaxPost") via JQuery. Dans le contrôleur, je vérifie la variable de ce formulaire. S'il est présent, j'utilise TempData pour stocker cette valeur avant d'appeler RedirectToAction pour afficher la vue "edit" pour le fichier nouvellement téléchargé. Dans la méthode d'action de réception, je vérifie à la fois Request.IsAjaxRequest() (comme je l'ai toujours fait) ainsi que ma valeur TempData pour déterminer si la requête est "ajax" ou non. Fonctionne très bien. Merci! – goombaloon

+0

@zowens: J'ai corrigé le code maintenant, mais oui, je l'ai réalisé après l'avoir fait et ensuite en regardant la méthode d'extension IsAjaxRequest qui est exactement la même chose. J'ai adapté le code à partir d'un filtre ActionFilter qui définit dynamiquement la page maître en fonction du type de requête, qui est bien sûr moins redondant que le code ci-dessus. – Jay

11

Vous devez définir l'en-tête "X-Requested-With" pour que la méthode IsAjaxRequest renvoie true. Voici comment vous le faites en jquery.

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

Le plug-in JQuery Form n'utilise pas XMLHttpRequest pour les téléchargements de fichiers. Il utilise un iframe. – goombaloon

+0

Cela aurait été la réponse parfaite, si cela a fonctionné ... –

+1

travaillé pour moi en angulaire '$ httpProvider.defaults.headers.common = {'X-Requested-With': 'XMLHttpRequest'};' – parliament

2

Je viens trébuché acr oss cette question et plus tard trouvé une meilleure solution, alors voici (pour tout le monde qui obtient ici de google):

jQuery formulaire plugin a deux options qui pourraient aider dans ce cas.

  1. si vous utilisez la demande de poste, il semble qu'il utilise toujours l'iframe, donc si vous n'avez pas besoin téléchargement de fichiers, la mise en iframe = false dans les options de formulaire aidé dans mon cas.

  2. Si vous avez besoin iframe pour fileuploads, vous pouvez utiliser la propriété de données des options pour tromper le

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

script complet avec les deux options ressemble que:

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

À partir de ASP.NET MVC 2 (et versions ultérieures), il existe une méthode d'extension sur le Request.

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

En utilisant une méthode telle que jQuery .load() sur une méthode de commande se traduira par Request.IsAjaxRequest() retour vrai.

Questions connexes