将AjaxOnlyAttribute和ChildActionOnlyAttribute组合到一个动作filter中
我希望能够在控制器上标记一个动作,从ajax调用和RenderAction调用。 问题是这两个属性都衍生或实现了不同的抽象。 一个出路是下一个:
[AjaxOnly] PartialViewResult GetViewAjax(int foo) { return GetView(foo); } [ChildActionOnly] PartialViewResult GetView(int foo) { ... }
但这根本不是很好。
我正在谈论的AjaxOnly属性是:
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 }
这种方法取自MVC3期货。 一个重要的评论为什么条件不是filterContext.HttpContext.Request.IsAjaxRequest()
是由开发团队做的,并说如下:
// 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.
这没有任何意义。 这两个属性是互斥的。 如果某个操作标有[ChildActionOnly]
,则客户端永远不能使用HTTP请求(无论是同步还是异步)直接访问它。 因此,如果您希望使用AJAX可以访问某个操作, [ChildActionOnly]
应该使用[ChildActionOnly]
属性来装饰它。
我不知道这个[AjaxOnly]
属性是什么以及它来自哪里但是根据它的实现方式,你可能需要调整它以便允许子动作请求,如果它仅依赖于Request.IsAjaxRequest()
方法。 例如,如果它是这样的:
public class AjaxOnlyAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { if (!filterContext.HttpContext.Request.IsAjaxRequest()) { filterContext.Result = new HttpNotFoundResult(); } } }
你可能想要像这样调整它:
public class AjaxOrChildActionOnlyAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { if (!filterContext.HttpContext.Request.IsAjaxRequest() && !filterContext.IsChildAction ) { filterContext.Result = new HttpNotFoundResult(); } } }
受到Darin的回答和ChildActionOnlyAttribute
的源代码的启发,这是我提出的解决方案,我认为它更好一点:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public class AjaxOrChildAttribute : ActionMethodSelectorAttribute { public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo) { return controllerContext.IsChildAction || controllerContext.RequestContext.HttpContext.Request.IsAjaxRequest(); } }
这样,validation即使在尝试执行之前也会完成,如果您键入url,则获得的错误与尝试任何无效的url完全相同。
- 异步(ajax)ASP.NET页面方法调用的请求生命周期是什么?
- 如何使用Ajax.BeginForm更新div并执行javascript函数?
- Image.FromStream(PostedFile.InputStream)失败。 (参数无效。)(AsyncFileUpload))
- GWT和.NET
- 在UpdatePanel中UpdateMethod之后刷新GridView
- 如何在自定义ASP.NET控件中使用ScriptManagerProxy?
- ASP.NET AJAX UpdatePanel和动态HTML插入问题(Telerik)
- 如何根据驻留在updatePanel中的DataGrid中的行选择更新控件?
- 使用ASP.NET和C#“Base-64字符串中的无效字符”