结合AjaxOnlyAttribute和ChildActionOnlyAttribute成一个行为过滤器 [英] Combining AjaxOnlyAttribute and ChildActionOnlyAttribute into one action filter

查看:675
本文介绍了结合AjaxOnlyAttribute和ChildActionOnlyAttribute成一个行为过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够以纪念控制器的操作来无论是从Ajax调用,并通过所谓的RenderAction。的问题是,无论这个属性派生或实现不同的抽象。一条出路是下一个:

  [AjaxOnly]
PartialViewResult GetViewAjax(INT富){返回GetView(富); }
[ChildActionOnly]
PartialViewResult GetView(INT富){...}

但是,这并不整齐的。


该AjaxOnly属性我说的是:

 公共密封类AjaxOnlyAttribute:ActionFilterAttribute
{
    #地区的公共成员    公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
    {
        如果(filterContext == NULL)
            抛出新的ArgumentNullException(filterContext);
        如果(filterContext.HttpContext.Request.Headers [X-要求,以]!=XMLHtt prequest)
            filterContext.Result =新HttpNotFoundResult();
    }    #endregion
}

这个方法是从MVC3期货拍摄。一个重要的原因注释条件不 filterContext.HttpContext.Request.IsAjaxRequest()是由开发团队制作,并说以下内容:

  // DEV10#939671  - 如果这个属性会说AJAX * *只,那么我们就需要检查头
//明确,否则客户端可以修改表单或查询字符串包含名称/值
//我们正在寻找对。


解决方案

这没有任何意义。这些两个属性是互斥的。如果操作标有 [ChildActionOnly] 永远不能直接通过使用一个HTTP请求的客户端访问(无论是同步或异步)。所以,如果你想要一个动作永远是使用AJAX访问,你永远不应该与 [ChildActionOnly] 属性装饰。

我不知道这个 [AjaxOnly] 属性是什么,它​​从何而来,但依赖于它是如何实现的,您可能需要调整它,以便让如果只依赖于 Request.IsAjaxRequest()方法子操作请求。例如,如果是这样的:

 公共类AjaxOnlyAttribute:ActionFilterAttribute
{
    公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
    {
        如果(!filterContext.HttpContext.Request.IsAjaxRequest())
        {
            filterContext.Result =新HttpNotFoundResult();
        }
    }
}

您可能要调整它是这样的:

 公共类AjaxOrChildActionOnlyAttribute:ActionFilterAttribute
{
    公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
    {
        如果(filterContext.HttpContext.Request.IsAjaxRequest()及!&放大器;
            !filterContext.IsChildAction
        )
        {
            filterContext.Result =新HttpNotFoundResult();
        }
    }
}

I want to be able to mark an action on controller to be called both from ajax calls and via RenderAction. The problem is that both this attributes derive or implement different abstractions. One way out is the next:

[AjaxOnly]
PartialViewResult GetViewAjax(int foo) { return GetView(foo); }
[ChildActionOnly]
PartialViewResult GetView(int foo) { ... }

But this is not neat at all.


The AjaxOnly attribute I am talking about is:

public sealed class AjaxOnlyAttribute : ActionFilterAttribute
{
    #region Public members

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext == null)
            throw new ArgumentNullException("filterContext");
        if (filterContext.HttpContext.Request.Headers["X-Requested-With"] != "XMLHttpRequest")
            filterContext.Result = new HttpNotFoundResult();
    }

    #endregion
}

This method is taken from MVC3 futures. An important comment why the condition is not filterContext.HttpContext.Request.IsAjaxRequest() was made by dev team and says the following:

// Dev10 #939671 - If this attribute is going to say AJAX *only*, then we need to check the header
// specifically, as otherwise clients can modify the form or query string to contain the name/value
// pair we're looking for.

解决方案

This doesn't make any sense. Those 2 attributes are mutually exclusive. If an action is marked with [ChildActionOnly] it can never be directly accessed by the client using an HTTP request (be it synchronous or asynchronous). So if you want an action to ever be accessible using AJAX, you should never decorate it with the [ChildActionOnly] attribute.

I don't know what this [AjaxOnly] attribute is and where it comes from but depending on how it is implemented you might need to tweak it in order to allow child action requests if it relies only on the Request.IsAjaxRequest() method. For example if it is something like this:

public class AjaxOnlyAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!filterContext.HttpContext.Request.IsAjaxRequest())
        {
            filterContext.Result = new HttpNotFoundResult();
        }
    }
}

you might want to tweak it like this:

public class AjaxOrChildActionOnlyAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!filterContext.HttpContext.Request.IsAjaxRequest() && 
            !filterContext.IsChildAction
        )
        {
            filterContext.Result = new HttpNotFoundResult();
        }
    }
}

这篇关于结合AjaxOnlyAttribute和ChildActionOnlyAttribute成一个行为过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆