コントローラー メソッドごとにセッション状態を無効にする方法。このようなフローでも適切に機能します。
- セッションが有効な request メソッド
- セッションを無効にした request メソッド
セッションが有効なリクエストメソッド - 値が保持されます (理由はわかりませんが、そうです)
/// <summary>
/// Enable session if there's an authenticated user or method in controller is marked with <see cref="SessionAttribute" /> or controller class is marked within <see cref="SessionAttribute" /> or <see cref="SessionStateAttribute" />
/// </summary>
public class AuthSessionControllerFactory : DefaultControllerFactory
{
protected override SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, Type controllerType)
{
if ( controllerType == null ) return SessionStateBehavior.Default;
return requestContext.HttpContext.User.Identity.IsAuthenticated
? SessionStateBehavior.Required
: GetDefaultSessionBehavior( requestContext, controllerType );
}
private static readonly ConcurrentDictionary<string, SessionStateBehavior> _sessionStateCache = new ConcurrentDictionary<string, SessionStateBehavior>();
protected SessionStateBehavior GetDefaultSessionBehavior(RequestContext requestContext, Type controllerType)
{
if ( !requestContext.RouteData.Values.Keys.Contains( "action" ) ) return SessionStateBehavior.Required;
var act = requestContext.RouteData.Values["action"].ToString();
return _sessionStateCache.GetOrAdd( controllerType + act,
(type => {
var typeCopy = controllerType;
//get current action
var methods = typeCopy.GetMethods().Where( m => m.Name == act ).ToArray();
foreach (var method in methods) {
//look for SessionAttribute on the method
var attr = Attribute.GetCustomAttribute( method, typeof( SessionAttribute ), false );
if ( attr != null ) return (( SessionAttribute )attr).Behavior;
//support default SessionState behavior
var controllerattr = typeCopy.GetCustomAttributes( typeof( SessionStateAttribute ), true )
.OfType<SessionStateAttribute>().FirstOrDefault();
if ( controllerattr == null )
{
var controllerattrCustom = typeCopy.GetCustomAttributes( typeof( SessionAttribute ), true )
.OfType<SessionAttribute>().FirstOrDefault();
if ( controllerattrCustom != null ) return controllerattrCustom.Behavior;
} else
return controllerattr.Behavior;
}
return SessionStateBehavior.Disabled;
}) );
}
}
Application_Start()
Global.asaxのメソッドに登録する
ControllerBuilder.Current.SetControllerFactory( new AuthUserSessionControllerFactory() );
ここに SessionAttribute クラスがあります - MS の SessionStateAttribute のように見えます - 唯一の違いは、これがメソッドに許可されていることです
[AttributeUsage( AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true )]
public sealed class SessionAttribute : Attribute
{
public SessionAttribute(SessionStateBehavior behavior)
{
Behavior = behavior;
}
public SessionStateBehavior Behavior { get; private set; }
}