2012-03-02 14 views
7

Hem ajax çağrılarından hem de RenderAction yoluyla çağrılacak denetleyicideki bir eylemi işaretleyebilmeyi istiyorum. Sorun, bu özelliklerin her ikisinin de farklı soyutlamalar türetmesi veya uygulanmasıdır. Bir çıkış yolu şu:AjaxOnlyAttribute ve ChildActionOnlyAttribute öğelerini tek eylem filtresine birleştirme

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

Ancak bu hiç de düzgün değildir.

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 
} 

Bu yöntem MVC3 vadeli alınır: AjaxOnly


Ben edilir bahsediyorum bağlıyor. durum şu dev ekibi tarafından yapılan ve der değildi filterContext.HttpContext.Request.IsAjaxRequest() neden önemli açıklama:

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

cevap

16

Bu, herhangi bir anlam ifade etmez. Bu 2 özellik karşılıklı olarak münhasırdır. Bir eylem [ChildActionOnly] ile işaretlenmişse, bir HTTP isteği kullanılarak istemci tarafından hiçbir zaman doğrudan erişilemez (senkronize veya senkronize olmama). Bu nedenle, AJAX kullanarak erişilebilir bir eyleme geçmek isterseniz, [ChildActionOnly] özniteliği ile asla dekore etmemelisiniz.

Bu [AjaxOnly] özniteliğinin ne olduğunu ve nereden geldiğini bilmiyorum ama nasıl uygulandığına bağlı olarak, yalnızca Request.IsAjaxRequest() yöntemine dayanıyorsa çocuk eylemi isteklerine izin vermek için ince ayar yapmanız gerekebilir.

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

bunu böyle ince ayar yapmak isteyebilirsin: Örneğin: böyle bir şeyse

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

Neden? İşleminizin hem RenderAction() hem de ajax istekleri aracılığıyla farklı yerlerde yeniden kullanıldığını varsayalım. Bunların farklı sayfalarda yeniden kullanıldığını varsayalım ve birçok yer için standart bir araç paneli çizerek farklı bağlamlarda –

+0

@ Hohhi'den biraz farklı olarak kullanıldığından, eyleminizin yalnızca bir AJAX çağrısı veya bir Çocuk eylemi aracılığıyla erişilebilir olmasını istiyorsunuz. ? –

+0

Tam olarak, öneriniz için teşekkür ederim, ben soru güncellemek ve bir zaman içinde ne kadar yol aldığımı anlatmak istiyorum –

1

Darin cevabı ve ChildActionOnlyAttribute 'ın kaynak kodu üzerinde ilham alan bu ben geldim çözümdür

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

Bu şekilde, doğrulama bile yürütmeye çalışırken önce yapılır ve url yazarsanız aldığınız hata tam sam: Ben bir nebze daha iyi olduğunu düşünüyorum hangi ile Herhangi bir geçersiz URL'yi deneyen biri.

İlgili konular