2012-03-02 5 views
7

コントローラでアクションをマークして、ajax呼び出しとRenderActionの両方から呼び出すことができるようにします。問題は、この両方の属性が異なる抽象を派生または実装していることです。 1つの方法は、次のとおりです:AjaxOnlyAttributeとChildActionOnlyAttributeを1つのアクションフィルタに結合する

[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. 

答えて

16

これはどんな意味がありません。これらの2つの属性は相互に排他的です。アクションが[ChildActionOnly]とマークされている場合、そのアクションはHTTP要求(同期または非同期)を使用してクライアントに直接アクセスすることはできません。したがって、AJAXを使用してアクションにアクセスできるようにするには、[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(); 
     } 
    } 
} 
+0

なぜですか?あなたのアクションが、RenderAction()とajaxリクエストの両方を介して異なる場所から再利用されたとします。これらが異なるページで再利用され、多くの場所でいくつかの標準ツールパネルを描画し、さまざまなコンテキストでわずかに異なるものが使用されていると仮定します。 –

+0

@Hohhiしたがって、AJAX呼び出しまたはChildアクション? –

+0

まさに、あなたの提案をありがとう、私は質問を更新し、いくつかの時間を取得する方法を教えてください –

1

ダーリンの答えと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(); 
    } 
} 

この方法では、検証も実行しようとする前に行われ、あなたはURLを入力するとあなたが得るエラーが正確なサムである:私はそれがほんの少しはましだと思うこれ、とアップ無効なURLを試してみてください。

関連する問題