会话到期属性不会在服务器上被触发

时间:2014-11-06 20:24:34

标签: c# asp.net-mvc-4 session-variables actionfilterattribute

我正在尝试跟踪会话过期,当我的开发PC上运行应用程序时,一切正常。但它不能按预期在实时服务器上运行。我已经重新启动服务器但没有运气!我正在运行Windows Server 2012(windows azure vm)和IIS 8。

我收到一个基于控制器的类似错误,其操作被触发。生成错误是因为控制器无法初始化,因为会话过期时会话变量_connectionstring为null。

如果我将sessionState更改为1并将timeout设置为2,那么重定向在服务器和开发环境中都能完美地工作。奇怪!!

我的问题是为什么动作过滤器在实时服务器环境中失效?它在开发环境下完美运行。我在这里缺少什么?

以下是我的代码。

Web.Config中:

<system.web>
    <sessionState mode="InProc" timeout="20" />
    <authentication mode="Forms">
        <forms loginUrl="~/Auth/Login" timeout="25" slidingExpiration="true" />
    </authentication>
</system.web>

过滤器配置:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new SessionExpireFilterAttribute());
        filters.Add(new LocsAuthorizeAttribute());
    }
}

过滤器:

public class SessionExpireFilterAttribute : ActionFilterAttribute
{

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.ActionDescriptor.GetCustomAttributes(typeof(SkipActionFilterAttribute), false).Any())
        {
            return;
        }

        HttpContextBase ctx = filterContext.HttpContext;
        //HttpContext ctx = HttpContext.Current;

        // check if session is supported
        if (ctx.Session != null)
        {
            // check if a new session id was generated
            if (ctx.Session.IsNewSession)
            {
                // If it says it is a new session, but an existing cookie exists, then it must
                // have timed out
                string sessionCookie = ctx.Request.Headers["Cookie"];
                if ((null != sessionCookie) && (sessionCookie.IndexOf("ASP.NET_SessionId") >= 0))
                {
                    if (filterContext.HttpContext.Request.IsAjaxRequest())
                    {
                        // For AJAX requests, we're overriding the returned JSON result with a simple string,
                        // indicating to the calling JavaScript code that a redirect should be performed.
                        filterContext.Result = new JsonResult { Data = "_Logon_" };
                    }
                    else
                    {
                        filterContext.Result = new RedirectToRouteResult(
                            new RouteValueDictionary {
                            { "action", "SessionTimeout" },
                            { "controller", "Session" }});
                    }
                }
            }
        }

        base.OnActionExecuting(filterContext);
    }
}

//[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class LocsAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext.ActionDescriptor.GetCustomAttributes(typeof(SkipActionFilterAttribute), false).Any())
        {
            return;
        }
        HttpContext ctx = HttpContext.Current;

        // If the browser session has expired...
        if (ctx.Session["UserName"] == null)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                // For AJAX requests, we're overriding the returned JSON result with a simple string,
                // indicating to the calling JavaScript code that a redirect should be performed.
                filterContext.Result = new JsonResult { Data = "_Logon_" };
            }
            else
            {
                // For round-trip posts, we're forcing a redirect to Home/TimeoutRedirect/, which
                // simply displays a temporary 5 second notification that they have timed out, and
                // will, in turn, redirect to the logon page.
                filterContext.Result = new RedirectToRouteResult(
                    new RouteValueDictionary {
                            { "action", "SessionTimeout" },
                            { "controller", "Session" }});
            }
        }
        else if (filterContext.HttpContext.Request.IsAuthenticated)
        {
            // Otherwise the reason we got here was because the user didn't have access rights to the
            // operation, and a 403 should be returned.
            filterContext.Result = new HttpStatusCodeResult(403);
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

public class SkipActionFilterAttribute : Attribute
{
}

2 个答案:

答案 0 :(得分:1)

最后我找到了不当行为的原因。

我的操作过滤器不会像IIS一样触发&gt;应用程序池&gt;高级设置&gt;空闲超时(分钟)设置达到会话状态之前的超时。默认值为20。

将值设置为0将禁用IIS idel超时。

答案 1 :(得分:0)

它会给出错误

错误:会话超时参数的值无效。输入小于或等于500000的正整数。

你可以尝试

if ((Session["project"] == null) && (Session["User"] == null) && (Label1.Text == "Label") && (Label2.Text == "Label"))

    {
        Session.Abandon();
        Response.Redirect("Default.aspx");
    }

    else
    {

        if ((Session["User"] == null) || (Session["project"] == null))

        {
            Session["project"] = Label1.Text;
            Session["User"] = Label2.Text;
        }

        if ((Label1.Text == "Label") || (Label2.Text == "Label"))

        {
            Label1.Text = Session["project"].ToString();
            Label2.Text = Session["User"].ToString();
        }

    }

并使您的身份验证模式为无,而不是IIS中的窗口&gt; Asp.net设置&gt;验证模式