Asp.net-Mvc
ASP.Net MVC 3:反向授權屬性
我有一個簡單的 ASP.Net MVC 3 應用程序,它有一些控制器和一些很好的操作。
現在,由於這是一個基於使用者的應用程序,大多數控制器操作都需要對使用者進行身份驗證。MVC 使用內置的 Authorize 屬性很好地處理了這個問題,您可以使用它來單獨裝飾控制器和/或操作。
最棒的是您可以將屬性僅應用於控制器,並且該給定控制器的所有操作也將應用它 - 節省了大量輸入;)
但我有一個控制器,可以說,10 個動作。但我希望其中一項操作不應用 Authorize 屬性。
是的,我可以將該屬性應用於其他 9 個並將其從控制器中刪除,這將完全滿足我的需要。但是有沒有辦法讓它應用到控制器並選擇排除其中一個動作?
實際上,想要類似…
[!Authorize]或者[NotAuthorize]我知道我可以創建一個自定義的來完成這項工作,但我想知道是否有內置的方法可以做到這一點?還是我必須將該屬性應用於所有其他 9 個操作?
Phil Haack 最近寫了一篇部落格文章來處理這個確切的場景:
他的解決方案包括編寫一個自定義的“條件過濾器提供程序”,它允許將過濾條件指定給操作方法的屬性。
細節和推理在他的文章裡,但是程式碼比較簡單。首先,創建過濾器提供程序:
using System; using System.Collections.Generic; using System.Linq; using System.Web.Mvc; public class ConditionalFilterProvider : IFilterProvider { private readonly IEnumerable<Func<ControllerContext, ActionDescriptor, object>> _conditions; public ConditionalFilterProvider( IEnumerable<Func<ControllerContext, ActionDescriptor, object>> conditions) { _conditions = conditions; } public IEnumerable<Filter> GetFilters( ControllerContext controllerContext, ActionDescriptor actionDescriptor) { return from condition in _conditions select condition(controllerContext, actionDescriptor) into filter where filter != null select new Filter(filter, FilterScope.Global, null); } }然後應用它:
IEnumerable<Func<ControllerContext, ActionDescriptor, object>> conditions = new Func<ControllerContext, ActionDescriptor, object>[] { (c, a) => c.Controller.GetType() != typeof(HomeController) ? new MyFilter() : null, (c, a) => a.ActionName.StartsWith("About") ? new SomeFilter() : null }; var provider = new ConditionalFilterProvider(conditions); FilterProviders.Providers.Add(provider);
請注意,在 ASP.NET MVC 4.0中添加了一個新屬性,該屬性正是這樣做的: