2011-07-02 23 views
41

Quiero usar vistas parciales con llamadas AJAX en ASP.NET MVC, y esta es la primera vez que lo estoy usando. Solo busqué para ver si hay algo especial que debería saber de antemano, y uno de ellos que me causa curiosidad, es ver si hay algún atributo especial que deba establecerse o que esté relacionado con las llamadas AJAX. Algo así como [ChildActionOnly] o [HttpGet]¿Hay algún atributo relacionado con AJAX que se establezca para las acciones del controlador ASP.NET MVC?

Respuesta

71

No creo que haya un atributo incorporado para ajax, pero no es demasiado difícil crear uno. puede crear AjaxOnly filtro como

public class AjaxOnlyAttribute : ActionMethodSelectorAttribute 
    { 
     public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo) 
     { 
      return controllerContext.RequestContext.HttpContext.Request.IsAjaxRequest(); 
     } 
    } 

y decorar sus métodos de acción como

[AjaxOnly] 
public ActionResult ajaxMethod() 
{ 

} 

Mira this post de otra forma de ejecución de este atributo

+1

Cómo MVC sabe que esta es realmente una solicitud de AJAX.¿Utiliza algún campo de encabezado HTTP personalizado? A veces, XmlHttpRequest no envía encabezados personalizados. –

+3

Utiliza el encabezado 'X-Requested-With' y este es el encabezado que se lee mediante el método' Request.IsAjaxRequest() '. –

+0

¿Hay alguna manera de hacer algo como esto con AttributeRouting? Implementa HttpRouteAttribute. – appsecguy

13

ASP.NET MVC proporciona un método de extensión para comprobar si una Solicitud es una Solicitud Ajax. Puede usarlo para decidir si desea devolver una vista parcial o un resultado json en lugar de una vista normal.

if (Request.IsAjaxRequest()) 
{ 
    return PartialView("name"); 
} 
return View(); 

Para limitar un método de acción a las llamadas Ajax solo puede escribir un atributo personalizado. En caso de una solicitud normal, este filtro devolverá una excepción http no encontrada 404.

[AttributeUsage(AttributeTargets.Method)] 
public class AjaxOnlyAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     if (!filterContext.HttpContext.Request.IsAjaxRequest()) 
     { 
      filterContext.HttpContext.Response.StatusCode = 404; 
      filterContext.Result = new HttpNotFoundResult(); 
     } 
     else 
     { 
      base.OnActionExecuting(filterContext); 
     } 
    } 
} 

puede utilizar de esa manera:

[AjaxOnly] 
public ActionResult Index() { 
    // do something awesome 
} 
3

Hay un [AjaxOnly] atributo previsto en la colecciónASP.NET MVC 3 Futuros. Es una parte del sitio oficial de ASP.NET MVC Codeplex que proporciona características antes de que se incluyan oficialmente en una versión futura de ASP.NET MVC.

Puede descargarlo here. Para usarlo, agregue una referencia al ensamblado Microsoft.Web.Mvc incluido en el paquete de lanzamiento.

Hay una explicación del atributo en la página this, junto con todas las demás funciones excelentes que puede usar.

2

mi solución sigue la [ChildActionOnly] aplicación:

public class AjaxOnlyAttribute : FilterAttribute, IAuthorizationFilter 
{ 
    public void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if (filterContext == null) 
      throw new ArgumentNullException("filterContext"); 
     if (!filterContext.HttpContext.Request.IsAjaxRequest()) 
      throw new InvalidOperationException(string.Format(
       CultureInfo.CurrentCulture, 
       "The action '{0}' is accessible only by an ajax request.", 
       filterContext.ActionDescriptor.ActionName 
      )); 
    } 
} 
+0

+1 para proporcionar una implementación que se puede aplicar a un controlador completo (en lugar de aplicarlo a todos y cada uno de los métodos de acción por separado, lo que puede ser una verdadera tensión). – xDisruptor

3

un spin-off de la respuesta de Muhammad que le permite especificar que no debe ser una petición ajax así:

using System.Web.Mvc; 
public class AjaxAttribute : ActionMethodSelectorAttribute 
{ 
    public bool ajax { get; set; } 
    public AjaxAttribute() { ajax = true; } 
    public AjaxAttribute(bool a) { ajax = a; } 
    public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo) 
    { 
     return ajax == controllerContext.HttpContext.Request.IsAjaxRequest(); 
    } 
} 

Esto le permite hacer cosas como ...

[Ajax] 
public PartialViewResult AjaxUpdatingPage() { 
    return PartialView(); 
} 

[Ajax(false)] 
public ViewResult NotAjaxUpdatingPage() { 
    return View(); 
} 
0

Para aquellos que buscan una solución .NET Core es ' s un poco más involucrado, ya que IsAjaxRequest() ya no está disponible.

A continuación se muestra el código que he utilizado en la producción en varios proyectos con gran efecto.

public class AjaxOnlyAttribute : ActionMethodSelectorAttribute 
{ 
    public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor actionDescriptor) 
    { 
    if(routeContext.HttpContext.Request.Headers != null && 
     routeContext.HttpContext.Request.Headers.ContainsKey("X-Requested-With") && 
     routeContext.HttpContext.Request.Headers.TryGetValue("X-Requested-With", out StringValues requestedWithHeader)) 
    { 
     if(requestedWithHeader.Contains("XMLHttpRequest")) 
     { 
     return true; 
     } 
    } 

    return false; 
    } 
} 
Cuestiones relacionadas