可从所有页面访问的属性,但每次会话只更改一次

时间:2016-02-16 13:59:31

标签: c# asp.net session

我不认为标题是我问题的最佳描述,但问题如下:

我有一个基类,如:

  public class BasePage : System.Web.UI.Page
    {
         public static ProjectDTO Project { get; set; }
         // some other code

         // Setting the project once per session.
         public void SetProject()
         {

           Project = (ProjectDTO)HttpContext.Current.Session["Project"];
           SiteMaster masterPage = Master as SiteMaster;
           masterPage.Project = Project;
         }

    }

然后我有一个aspx页面,如:

public partial class SomePage: BasePage
{
    protected void Page_Load(object sender, EventArgs e)
    {
     //callling the base method to set the project
       SetProject();
    }

    //some db method which requires the Project.Id property.
    GetSomeInfo(Project.Id)
    {
    //irelevant code
    }

}

一切正常,但是,当我同时在线有2位用户时,他们显然会调用SetProject方法,如果其中一位使用GetSomeInfo方法,{{1} }属性将是最新的一个集合,而不是当前用户会话中的集合。

任何人都可以帮我解决这个问题吗?

PS:

  • 每次我必须使用项目时,一个脏修复就是读取会话变量,不会有问题,但是我的页面有10个需要该属性的方法(很多冗余代码)
  • 辅助修复是在Project.Id上声明公共属性并使用它,但是,我会发现SomePage中的Project多余,我不喜欢这种方法,因为有很多页面需要BasePage属性并使用Project(对属于该项目的对象进行过滤,搜索等)

编辑经过多次测试,同时有2个不同的用户,在Glubus评论之后,只有在为其中一个用户(未加载的用户)加载页面时才会出现问题当其他用户加载页面时,任何内容都会从数据库中得到错误的结果。)

EDIT2 工作流程如下: 用户进入主页,其中有可用的项目列表(从数据库中读取) - >点击一个项目(当用户点击项目时,我设置一个会话变量以便稍后阅读)。然后,用户可以查看/使用与该项目相关的其他数据。

EDIT3 当用户单击项目时,他们将导航到BasePage页面。在Dashboard甚至我设置会话变量,例如:

Page_Load

ProjectDTO课程:

public partial class Dashboard : BasePage
{
  protected void Page_Load(object sender, EventArgs e)
    {
        int projectId;
        int.TryParse(Request.QueryString["projectId"], out projectId);
        if (projectId > 0)
            {
                Session["Project"] = ProjectSvc.GetProjectById(projectId);
                SetProject();
            }
    }
}

我将public class ProjectDTO { public int idProject { get; set; } public string Title { get; set; } public string Users { get; set; } public string Description { get; set; } } 设置为Project,因为我的标签需要在屏幕上显示Site Master名称和说明。

2 个答案:

答案 0 :(得分:0)

也许是最糟糕的情景解决方案 - 但...... 如果您真的打算让所有后续用户都可以访问Project变量,那么您可能需要远离会话并将其声明为静态?

这样它将在应用程序范围内共享,保留最后指定的值。

答案 1 :(得分:0)

为了从所有地方(包括WebMethods)从当前Session访问Project,在BasePage中声明一个直接访问Session的静态readonly属性。

public class BasePage : System.Web.UI.Page
{
             public static ProjectDTO Project 
             { 
                get {return (ProjectDTO)HttpContext.Current.Session["Project"];}
             }
             // some other code

             // Passing the Project to the Master.
             public void SetProject()
             {
               SiteMaster masterPage = Master as SiteMaster;
               masterPage.Project = Project;
             }
}

如果您还使用BasePage.Project从Site Master访问当前项目,则可以完全删除SetProject()调用。

在测试期间,请确保您没有使用相同的浏览器实例进行测试。当会话管理通过cookie发生并且您有两个用户登录到同一个浏览器实例时,他们实际上将使用相同的ASP.net会话。