2009-11-05 17 views
9

Estoy usando el complemento JQuery Form para hacer una carga de archivos en una aplicación ASP.NET MVC. Aprendí que, dado que se utiliza un iframe para la carga de archivos (en lugar de XMLHttpRequest, que no es posible), falla la comprobación del lado del servidor para IsAjaxRequest.Detección de IsAjaxRequest() con ASP.NET MVC y JQuery Form Plugin/File Upload

He visto algunas publicaciones relacionadas con esta pregunta, pero no he encontrado ninguna buena solución para solucionar este problema. Al igual que con el resto de mi aplicación, me gustaría poder admitir escenarios habilitados para JavaScript y JavaScript desactivados, por lo que me gustaría detectar si una solicitud es ajax o no.

Me doy cuenta de que el enfoque iframe que se utiliza no es técnicamente ajax, pero estoy tratando de imitar un efecto Ajax.

Cualquier sugerencia sería bienvenida.

Respuesta

9

Me acabo de dar cuenta Estoy totalmente de no responder a la pregunta, así que estoy añadiendo a la parte superior aquí, y dejando mi viejo respuesta a continuación:

El problema es cuando la publicación de un archivo a través de un iFrame, el El encabezado "X-Requested-With" no está configurado y no puede establecer encabezados de solicitud específicos para un POST de forma normal en Javascript. Tendrá que recurrir a otros trucos, como enviar un campo oculto con su POST que contiene un valor, y luego cambiar o anular el método de extensión "IsAjaxRequest" para verificar también esta condición. How to override an existing extension method?

Probablemente la mejor opción sería probablemente para incluir su propio método de extensión con un nombre diferente, basado fuera de la MVC código del método de extensión por defecto con los cambios de detectar su iFrame subir POST, y luego usar el método de extensión en cualquier lugar donde esperas necesitarlo


jQuery realmente establece el 'X-solicitada-Con' cabecera de 'XMLHttpRequest' por defecto. Es bastante útil siempre que tenga cuidado de hacer todas sus llamadas AJAX a través de jQuery.

Dependiendo de sus necesidades, es fácil de configurar la detección de un filtro de acción para usarlo cuando sea necesario, o incluso construir en una clase de controlador de este modo:

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

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

Y el uso de la aplicación:

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

      return View(); 
    } 
} 
+0

En su código , IsAjaxRequest siempre es cierto, lo que frustra el propósito del código ... además, esa es la misma funcionalidad que existe en el método de extensión ... así que eso realmente no te ayuda. – zowens

+1

Gracias por la información. Siguiendo su ejemplo, terminé agregando dinámicamente un valor de formulario oculto ("isFileUploadAjaxPost") a través de JQuery. En el controlador, verifico la variable de forma. Si está presente, uso TempData para almacenar este valor antes de llamar a RedirectToAction para mostrar la vista de "edición" para el archivo recién cargado. En el método de acción de recepción, verifico tanto Request.IsAjaxRequest() (como he estado haciendo todo el tiempo) como mi valor de TempData para determinar si la solicitud es "ajax" o no. Funciona genial. ¡Gracias! – goombaloon

+0

@zowens: He corregido el código ahora, pero sí, me di cuenta después de hacerlo y luego miro el método de extensión IsAjaxRequest que es exactamente el mismo. Adapte el código de un ActionFilter que establece dinámicamente la página maestra en función del tipo de solicitud que, por supuesto, es algo menos redundante que el código anterior. – Jay

11

Debe configurar el encabezado "X-Requested-With" para que el método IsAjaxRequest devuelva verdadero. Así es como lo haces en jquery.

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

El complemento JQuery Form no utiliza XMLHttpRequest para cargas de archivos. Utiliza un iframe. – goombaloon

+0

Esta habría sido la respuesta perfecta, si funcionó ... –

+1

funcionó para mí en angular '$ httpProvider.defaults.headers.common = {'X-Solicitado-Con': 'XMLHttpRequest'};' – parliament

2

simplemente me encontré acr Osea esta pregunta y luego encuentra una mejor solución, así que aquí está (para todos los que llegan aquí desde google):

El complemento jQuery form tiene dos opciones que podrían ayudar en este caso.

  1. si está utilizando la solicitud posterior, parece que siempre está usando el iframe, por lo que si usted no necesita la carga de archivos, el establecimiento de iframe = false en las opciones de la forma contribuyó en mi caso.

  2. Si necesita iframe para fileuploads, puede utilizar la propiedad de datos de las opciones para engañar al

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

guión completo con las dos opciones parece que:

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

A partir de ASP.NET MVC 2 (y en adelante) hay un método de extensión en el Request.

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

Utilizando un método jQuery como .load() en un método controlador dará lugar a Request.IsAjaxRequest() regresar cierto.