2014-02-28 32 views
1

我想在我的應用程序中創建一些自定義過濾器行爲過濾器檢查會話MVC3

登錄成功後我一直登錄的用戶信息的會議,並要檢查的會話過期或沒有(如果會話過期我想要重定向到登錄頁面),我需要一個過濾器。

public class MyActionFilterAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     SchoolApp.ViewModels.CurrentSessionModel model=(SchoolApp.ViewModels.CurrentSessionModel)HttpContext.Current.Session["mySession"]; 
     if (model == null) 
     { 
      //Redirect to Login page 
     } 
     else 
     { 
      base.OnActionExecuting(filterContext); 
     } 
    } 
} 

但問題是,即使在加載登錄頁面時,這會爲每個rquests啓動。所以我怎麼能做一個有用的過濾器控制,檢查會話

回答

1

看起來你想在那裏做錯事。檢查你的web.config文件 - 它應該有這樣一節:

<authentication mode="Forms"> 
    <forms loginUrl="http://www.your_domain.com/login" name="cookie_name" defaultUrl="default_url" domain="your_domain" enableCrossAppRedirects="true" protection="All" slidingExpiration="true" cookieless="UseCookies" timeout="1440" path="/" /> 
</authentication> 

如果您的會話過期(與cookie_name非cookie的存在了) - 用戶將被自動重定向到loginUrl

如果你仍然想使用過濾器 - 有解決方案,使您可以排除一些控制器/動作全局過濾:

假設你擁有的global.asax.cs方法:

private static void RegisterGlobalFilters(GlobalFilterCollection filters) 
{ 
    IFilterProvider[] providers = FilterProviders.Providers.ToArray(); 
    FilterProviders.Providers.Clear(); 
    FilterProviders.Providers.Add(new ExcludeFilterProvider(providers)); 

    filters.Add(DependencyResolver.Current.GetService<MyFilter>(), 2); // add your global filters here 
} 

說它在你的global.asax.cs:

RegisterGlobalFilters(GlobalFilters.Filters); 

過濾器提供商類的樣子:

public class ExcludeFilterProvider : IFilterProvider 
{ 
    private readonly FilterProviderCollection _filterProviders; 

    public ExcludeFilterProvider(IFilterProvider[] filters) 
    { 
     _filterProviders = new FilterProviderCollection(filters); 
    } 

    public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) 
    { 
     Filter[] filters = _filterProviders.GetFilters(controllerContext, actionDescriptor).ToArray(); 
     if (filters.Select(f => f.Instance).OfType<OverrideExcludeFilter>().Any()) 
      return filters; 
     IEnumerable<ExcludeFilterAttribute> excludeFilters = (from f in filters where f.Instance is ExcludeFilterAttribute select f.Instance as ExcludeFilterAttribute); 
     var excludeFilterAttributes = excludeFilters as ExcludeFilterAttribute[] ?? excludeFilters.ToArray(); 
     if (excludeFilterAttributes.FirstOrDefault(f => f.AllFilters) != null) 
     { 
      return new Collection<Filter>(); 
     } 

     var filterTypesToRemove = excludeFilterAttributes.SelectMany(excludeFilter => excludeFilter.FilterTypes); 
     IEnumerable<Filter> res = (from filter in filters where !filterTypesToRemove.Contains(filter.Instance.GetType()) select filter); 
     return res; 
    } 
} 

ExcludeFilter屬性類:

public class ExcludeFilterAttribute : FilterAttribute 
{ 
    private readonly Type[] _filterType; 

    public ExcludeFilterAttribute(bool allFilters) 
    { 
     AllFilters = allFilters; 
    } 

    public ExcludeFilterAttribute(params Type[] filterType) 
    { 
     _filterType = filterType; 
    } 

    /// <summary> 
    /// exclude all filters 
    /// </summary> 
    public bool AllFilters { get; private set; } 

    public Type[] FilterTypes 
    { 
     get 
     { 
      return _filterType; 
     } 
    } 
} 

和用法示例:

[ExcludeFilter(new[] { typeof(MyFilter) })] 
    public ActionResult MyAction() 
    { 
     //some codes 
    } 

所以這種方式你的MyFilter類型的過濾器將不會觸發指定的動作

+0

你可以發佈自定義過濾器的一些工作示例 –

+0

@JMat Aint這個工作? – Sergio