2009-05-13 19 views
5

Belirli bir eylemde değil, Denetleyici düzeyinde bir Öznitelik eklemenin bir yolu var mı? Örneğin, benim Denetleyicimde 10 Eylemlerim olsaydı ve bu Eylemlerin yalnızca 1'inin oluşturduğum belirli bir öznitelik gerektirmediğini söyleyin.Denetleyiciler ve Eylemler MVC Öznitelikleri

 
[MyAttribute] 
public class MyController : Controller 
{ 
    public ActionResult Action1() {} 
    public ActionResult Action2() {} 

    [Remove_MyAttribute] 
    public ActionResult Action3() {} 
} 
Potansiyel olarak başka bir kontrol içine bu eylem taşımak (ama bu sevmiyorum) ya da ben Action3 hariç tüm eylemlere MyAttribute geçerli olabilir ama daha kolay bir yolu varsa sadece düşünce olabilir

?

cevap

3

Johannes doğru çözümü verdi ve nasıl kodladım ... umarım diğer insanlara yardım eder.

 
[MyFilter("MyAction")] 
public class HomeController : Controller 
{ 
    public ActionResult Action1... 
    public ActionResult Action2... 
    public ActionResult MyAction... 
} 

public class CompressFilter : ActionFilterAttribute 
{ 
    private IList _ExcludeActions = null; 

    public CompressFilter() 
    { 
     _ExcludeActions = new List(); 
    } 

    public CompressFilter(string excludeActions) 
    { 
     _ExcludeActions = new List(excludeActions.Split(',')); 
    } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     HttpRequestBase request = filterContext.HttpContext.Request; 

     string currentActionName = (string)filterContext.RouteData.Values["action"]; 

     if (_ExcludeActions.Contains(currentActionName)) 
      return; 

     ... 
    } 
+0

Teşekkürler David! Tam olarak aklımda olan şey! –

2

Ana özniteliği bunu geçirerek belirli bir işlem çıkarabiliyordunuz:

Benim örnek kafasından oldu

[MyAttribute(Exclude="Action3")] 

DÜZENLEME (aşağıdaki VB.NET olduğunu görebileceğiniz gibi,

Sen geçersiz kılmak zorunda
<Models.MyAttribute(Exclude:="Action3")> _ 
Public Class MyController 
Inherits System.Web.Mvc.Controller 

End Class 
3

/varsayılan özelliğini uzatmak ve özel bir con ekleyin: yanlış gittiği belki de bu, bu şimdiye hayata nasıl) var dışlanmaya izin vermek için structor. Veya özel özniteliğinizi hariç tutma için oluşturabilirsiniz (örneğinizde [Remove_MyAttribute]).

+0

Doğru yöndeki nokta için teşekkürler. Cevabınızı dile getirdikten sonra çözümümün altında cevabımı verdim. – David

2

yapmaya çalışıyorsun ne için olağan desen ve nitelik uygulanır olup olmadığını gösteren bir boolean parametresi ile atfetmektir.

Ör:

[ComVisible] which is equivalent with [ComVisible(true)] 

or 

[ComVisible(false)] 

davanızı inf sahip olacaktır:

[MyAttribute] // defaults to true 

and 

[MyAttribute(false)] for applying the attribute on excluded members 
+0

Böylece, Denetleyici seviyesinde tanımlarsınız ve daha sonra Eylemin kendisinde etkili bir şekilde geçersiz kılınız. Bu fikri beğenirim ve eylem adlarıyla karşılaştırmaktan daha kolaydır. Çözümünüz için teşekkürler. Ben hata ayıklarken yani (yanlış) MyAttribute ancak üzerinde tanımlanmış bir Yardımcısı yönteminden RenderAction kullanıyorum – David

+0

satışlardaki benim özniteliği içindeki özel değişken sıfırlama yapmayı doğru yapıcı çağırır. Herhangi bir fikir? – David

3

ben cevabım oyuna biraz geç (neredeyse dört yıl) olduğunu biliyorum, ama bu soruya rastladım Gelecekte başkalarına yardımcı olması durumunda, asıl sorunun ne yapmak istediğini hemen hemen yapmamı sağlayan bir çözüm önermek istedim. Çözüm, AttributeUsage adı verilen küçük bir gem içerir; bu, denetleyicideki (ve hatta tüm temel denetleyicilerinde!) Bir öznitelik belirtmemizi ve gerektiğinde bireysel eylemler veya alt denetleyicileri geçersiz kılmamızı (yok saymayı/kaldırmayı) sağlar. Sadece en granüler özniteliğin gerçekte ateşlendiği yere "kademeli" olacaklardır, yani en spesifik (temel denetleyiciler), daha spesifik (türetilmiş denetleyiciler), en özel (eylem yöntemleri).

[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method, Inherited=true, AllowMultiple=false)] 
public class MyCustomFilterAttribute : ActionFilterAttribute 
{ 

    private MyCustomFilterMode _Mode = MyCustomFilterMode.Respect;  // this is the default, so don't always have to specify 

    public MyCustomFilterAttribute() 
    { 
    } 
    public MyCustomFilterAttribute(MyCustomFilterMode mode) 
    { 
     _Mode = mode; 
    } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     if (_Mode == MyCustomFilterMode.Ignore) 
     { 
      return; 
     } 

     // Otherwise, respect the attribute and work your magic here! 
     // 
     // 
     // 
    } 

} 

public enum MyCustomFilterMode 
{ 
    Ignore = 0, 
    Respect = 1 
} 

(ı nitelikler gibi duydum, bu yüzden özellik hakkında bazı özelliklerini koymak Çok üst burada sihirli çalışmasını sağlayan şeylerin gerçekten:

İşte nasıl! Onları/basamaklarını miras izin vermek, ancak bunlardan sadece birini sağlayan yürütmek için)

İşte

var şimdi nasıl kullanıldığını.

[MyCustomFilter] 
public class MyBaseController : Controller 
{ 
    // I am the application's base controller with the filter, 
    // so any derived controllers will ALSO get the filter (unless they override/Ignore) 
} 

public class HomeController : MyBaseController 
{ 
    // Since I derive from MyBaseController, 
    // all of my action methods will also get the filter, 
    // unless they specify otherwise! 

    public ActionResult FilteredAction1... 
    public ActionResult FilteredAction2... 

    [MyCustomFilter(Ignore)] 
    public ActionResult MyIgnoredAction... // I am ignoring the filter! 

} 

[MyCustomFilter(Ignore)] 
public class SomeSpecialCaseController : MyBaseController 
{ 
    // Even though I also derive from MyBaseController, I can choose 
    // to "opt out" and indicate for everything to be ignored 

    public ActionResult IgnoredAction1... 
    public ActionResult IgnoredAction2... 

    // Whoops! I guess I do need the filter on just one little method here: 
    [MyCustomFilter] 
    public ActionResult FilteredAction1... 

} 

Bu derler umut, biraz s bazı benzer koddan çekti ve yaptım Üzerinde arama yapın ve değiştirin, bu yüzden mükemmel olmayabilir.

+0

PS, ben açıkça belirtmek unuttum Bence, bu yaklaşımın avantajı, sen eylem adları temsil sihirli dizeleri var, ne de her şeyin üstünde eşlemeyi güncel tutmak için hatırlamak gerek kalmamasıdır : sen giderken altındaki gerekli sen giderken sadece saygı ve geriye/Ignore saygısız, anahtarı süsleyin. İyi şanslar! – Funka

+0

kuşaklar için: Ayrıca http://stackoverflow.com/questions/4390541/asp-net-mvc-ignore-custom-attribute-in-a-base-controller-class/5070193#5070193 bakın – Funka

İlgili konular