ASP.Net中静态类的生命

时间:2013-08-14 06:15:28

标签: c# asp.net session

在我的UI图层中,我将一些时区信息存储在会话状态中。

我现在需要访问我的服务/业务/数据层中的时区。

从我的UI层,我传递登录用户的UserID,我的数据库为该用户存储了时区信息。我宁愿不用用户ID传递时区。

时区仅用于时间很重要的几个电话。 (项目已经启动,今天是休假的人......等等。)

我想可能有一个静态类,它在所有层(服务/业务/数据)上引用,它有一个时区信息字段。我希望它是静态的,以便我可以参考它:

var CurrentDate = CommonClass.GetLocatDateTime(_userId);

这可能会返回DateTime

然后,如果CurrentDate == null,使用UserId,从该数据库获取该用户的TimeZoneId - 因此,数据库调用只会发生一次,并且只有在之前没有发生时才会发生。

但是,静态类何时“出生”和“被杀”?

是每个用户的会话吗?或者是在Asp.Net应用程序运行时? 当我说用户会话时,我的意思是,每次用户点击某些内容时,都会创建一个新会话,因此,我的静态类会被创建吗?或者静态类对所有其他会话“可见”吗?我希望它仅限于当前用户。

4 个答案:

答案 0 :(得分:5)

  

但是,静态类何时“出生”和“被杀”?

您不需要该类的引用来访问静态成员。所以从来没有出生或死亡。

  

是每个用户的会话吗?

不,它对您的整个应用程序来说是全局的,并且在所有用户之间共享。

  

我希望它仅限于当前用户。

然后忘记静态成员并使用会话。

答案 1 :(得分:1)

静态类成员在用户会话之间共享。但是,我没有看到静态方法的任何可能问题。只要您不存储共享(静态)状态(=您不使用静态字段/属性),您就是安全的。

答案 2 :(得分:1)

静态等同于单例 - 对整个应用程序而言通用,因此对所有用户都是如此。您需要基于会话的方法来实现此目的。 但是,如果您无权访问会话(例如在业务库中),则可以使用单例方法(代码示例如下)。

编辑:使用单例方法实现此目的的代码示例(类似于静态但更易于维护)。它使用EF代码第一种方法,所以如果你不使用EF,你应该调整它:

编辑2:这是你应该如何使用它:

在用户时区获取时间:

var userId = 5; // assuming 5 a valid user. If not found, current local timezone will be used (`DateTime.Now`)
var localTime = UserDateTime.Instance.GetTime(userId);`

如果添加了新用户或修改了现有用户,您可以重新加载时区:(您可以根据需要进一步优化)。

UserDateTime.Instance.LoadTimezones();

实现:

namespace YourApp
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Data.Entity;

    class UserDateTime
    {
        public static readonly UserDateTime Instance = new UserDateTime();

        private UserDateTime() // singleton
        {
            LoadTimezones();
        }

        private Dictionary<int, string> _userTimezones = new Dictionary<int, string>();
        public DateTime GetTime(int userId)
        {
            if (_userTimezones.ContainsKey(userId))
                return TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById(_userTimezones[userId]));
            else
                return DateTime.Now; // You could throw an error.
        }


        public void LoadTimezones()
        {
            using (var db = new YourDbContext())
            {
                _userTimezones = db.UserTimezones.ToDictionary(t => t.UserId, t => t.TimezoneId);
            }
        }
    }


    class UserTimezone
    {
        public int UserId { get; set; }
        public string TimezoneId { get; set; }
    }

    class YourDbContext : DbContext
    {
        public DbSet<UserTimezone> UserTimezones { get; set; }
    }
}

编辑:源自ASP Security Kit

答案 3 :(得分:1)

根据我的经验,它是这样的。

  • 用户点击网站。
  • 网站启动
  • 如果调用静态类 - 将调用其静态构造函数,静态类将“生成”
  • 用户完成会话
  • 应用程序和静态类保持活力
  • 另一位用户点击网站并访问静态类
    • 静态类'构造函数未被调用,因为静态类已经“已经生成”并且访问其任何静态变量将与之前的用户保持相同
  • 没有其他人在超时期限内访问网站(通常在iis上设置为10分钟左右)
  • 网站关闭,静态类处理完毕,下一个用户将重新开始