是否为ASP.NET MVC控制器操作设置了与AJAX相关的任何属性?

时间:2011-07-02 18:13:40

标签: asp.net-mvc asp.net-mvc-3 attributes aop

我想在ASP.NET MVC中使用部分视图和AJAX调用,这是我第一次使用它。我只是想搜索一下我之前应该知道的是否有什么特别之处,而且我很好奇的是,是否有任何应该设置或与AJAX调用相关的特殊属性?类似[ChildActionOnly][HttpGet]

的内容

6 个答案:

答案 0 :(得分:79)

我不认为ajax有内置属性,但创建一个属性并不太难。您可以像

一样创建AjaxOnly过滤器
public class AjaxOnlyAttribute : ActionMethodSelectorAttribute 
    {
        public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
        {
            return controllerContext.RequestContext.HttpContext.Request.IsAjaxRequest();
        }
    }

并装饰你的行动方法,如

[AjaxOnly]
public ActionResult ajaxMethod()
{

}

请查看this post以了解实现此属性的另一种方法

答案 1 :(得分:18)

ASP.NET MVC提供了一种扩展方法来检查Request是否是Ajax请求。您可以使用它来决定是否要返回部分视图或json结果而不是普通视图。

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

要将操作方法​​限制为Ajax调用,只能编写自定义属性。如果是正常请求,此过滤器将返回404未找到的http异常。

[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);
        }
     }
}

你可以这样使用它:

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

答案 2 :(得分:4)

分拆穆罕默德的回答,让你指明它也不一定是ajax请求:

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();
    }
}

这可以让你做像...这样的事情。

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

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

答案 3 :(得分:3)

ASP.NET MVC 3 Futures 集合中提供了 [AjaxOnly] 属性。它是官方ASP.NET MVC Codeplex站点的一部分,它在正式包含在ASP.NET MVC的未来版本之前提供功能。

您可以下载here。要使用它,请添加对发布包中包含的 Microsoft.Web.Mvc 程序集的引用。

this页面上的属性说明,以及您可以使用的所有其他强大功能。

答案 4 :(得分:2)

我的解决方案遵循[ChildActionOnly]实施:

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

答案 5 :(得分:0)

对于那些寻找.NET Core解决方案的人来说,由于IsAjaxRequest()已不再可用,因此需要更多参与。

以下是我在多个项目中用于生产的代码,效果非常好。

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