【问题标题】:ASP.NET 2.0: Problem in Httpcontext.current.session.add()ASP.NET 2.0:Httpcontext.current.session.add() 中的问题
【发布时间】:2009-08-01 07:37:11
【问题描述】:

谁能帮我找出以下问题的解决方案。

  1. 在 ASP.NET 网站中:在 Application_OnPostAuthenticate() 事件中,我编写的任何代码都会针对每个请求执行。因此,由于这个 customidentity 对象,每次请求都会调用 countryid 和 weatherid(调用数据库以获取值)。它影响页面的响应时间和不必要的代码执行。

    void Application_OnPostAuthenticateRequest(object sender, EventArgs e) {

    // Get a reference to the current User
    
    IPrincipal objIPrincipal = HttpContext.Current.User;
    
    // If we are dealing with an authenticated forms authentication request
    
    if ((objIPrincipal.Identity.IsAuthenticated) && (objIPrincipal.Identity.AuthenticationType == "Forms"))
    {
        CustomPrincipal objCustomPrincipal = new CustomPrincipal();
        objCustomPrincipal = objCustomPrincipal.GetCustomPrincipalObject(objIPrincipal.Identity.Name);
        HttpContext.Current.User = objCustomPrincipal;
        CustomIdentity ci = (CustomIdentity)objCustomPrincipal.Identity;            
        HttpContext.Current.Cache["CountryID"] = FatchMasterInfo.GetCountryID(ci.CultureId);
        HttpContext.Current.Cache["WeatherLocationID"] = FatchMasterInfo.GetWeatherLocationId(ci.UserId);
        Thread.CurrentPrincipal = objCustomPrincipal;
    }
    

    }

当我尝试更改代码时解决这个问题如下 HttpContext.Current.Session.Add("test", FatchMasterInfo.GetWeatherLocationId(ci.UserId););代替缓存,我发现了愚蠢的错误 "对象引用未设置为对象的实例"

我不知道我们是否可以在 Application_OnPostAuthenticate() 事件中存储会话变量?

【问题讨论】:

    标签: asp.net global-asax


    【解决方案1】:

    您可以稍后在请求中尝试执行此操作,例如在 PreRequestHandlerExecute 事件中:

    protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
    {
        IPrincipal objIPrincipal = HttpContext.Current.User;
        if ((objIPrincipal.Identity.IsAuthenticated) && (objIPrincipal.Identity.AuthenticationType == "Forms"))
        {
            HttpSessionState session = HttpContext.Current.Session;
            CustomPrincipal objCustomPrincipal = new CustomPrincipal();
            if (session[objIPrincipal.Identity.Name] == null)
            {
                // get data from database or wherever
                objCustomPrincipal = objCustomPrincipal.GetCustomPrincipalObject(objIPrincipal.Identity.Name);
                CustomIdentity ci = (CustomIdentity)objCustomPrincipal.Identity;
                Object countryID = FatchMasterInfo.GetCountryID(ci.CultureId);
                Object weatherLocationID = FatchMasterInfo.GetWeatherLocationId(ci.UserId);
                // save in session (not cache as cache is application-wide, not per-user):
                session.Add(objIPrincipal.Identity.Name, objCustomPrincipal);
                session.Add(objIPrincipal.Identity.Name + "_CountryID", countryID);
                session.Add(objIPrincipal.Identity.Name + "_WeatherLocationID", weatherLocationID);
            }
            else
            {
                // already have custom principal object in session
                objCustomPrincipal = (CustomPrincipal)session[objIPrincipal.Identity.Name];
            }
    
            // set the custom principal object to context/thread
            HttpContext.Current.User = objCustomPrincipal;
            Thread.CurrentPrincipal = objCustomPrincipal;
        }
    }
    

    【讨论】:

    • @ironsam,非常感谢。我有几个关于相同的查询 1. 通过使用 GetCustomPrincipalObject() 我正在获取登录用户的角色和权限。在这里查找角色和权限是一种很好的做法,或者我们需要更改代码并将其放在其他地方。 2. 为什么 sessionstart 事件不适合 session.add() ?同时我正在实施您提供的解决方案。我希望它能解决这个问题。
    • 编辑:@ironsam,我已经尝试过您提供的解决方案。当我使用以下代码在 aspx 页面获取用户时 CustomIdentity ci = HttpContext.Current.User.Identity as CustomIdentity; ci 的值为 null。我没有明白我做错了什么?
    • 如果您需要在 aspx 页面上,您应该能够从会话对象中获取 CustomIdentity:CustomPrincipal pi = (CustomPrincipal)session[objIPrincipal.Identity.Name]; CustomIdentity ci = (CustomIdentity)pi.Identity;至于最佳实践以及请求中发生某些事件时,这可能会有所帮助msdn.microsoft.com/en-us/library/ms178473.aspx>。
    • 嗨,你能解释一下,如果我们在我的 Httpcontext 中有自定义的身份和原则,那么从会话中获取它好吗?是的,我们可以从 session 和 httpcontext 中获取它。但是我们应该使用什么?
    • 我认为从 HttpContext 获取它会更好,但是如果您设置的自定义设置在请求的剩余生命周期中无法立即使用(可能与何时你设置它,在这种情况下是 PreRequestHandlerExecute 事件),然后如果可能的话,只使用会话一。
    【解决方案2】:

    您可能不想在每个请求中发生的任何事件中访问会话。有些请求甚至没有会话(例如,大量的 Web 服务调用,或者对加载静态资源的 WebResource.axd 的调用)。

    【讨论】:

      【解决方案3】:

      在向缓存对象添加值之前,检查它是否已经存在于缓存中。

      【讨论】:

        【解决方案4】:

        您可能没有启用会话状态。它是否可以在其他任何地方使用(例如在 Web 表单的显示中)?

        在 web.config 中的 system.web 元素下查找 <sessionState> 元素,确保它已打开(将其设置为 InProc,除非您有网络场)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-03-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多