在我的UI图层中,我将一些时区信息存储在会话状态中。
我现在需要访问我的服务/业务/数据层中的时区。
从我的UI层,我传递登录用户的UserID,我的数据库为该用户存储了时区信息。我宁愿不用用户ID传递时区。
时区仅用于时间很重要的几个电话。 (项目已经启动,今天是休假的人......等等。)
我想可能有一个静态类,它在所有层(服务/业务/数据)上引用,它有一个时区信息字段。我希望它是静态的,以便我可以参考它:
var CurrentDate = CommonClass.GetLocatDateTime(_userId);
这可能会返回DateTime
。
然后,如果CurrentDate == null,使用UserId,从该数据库获取该用户的TimeZoneId - 因此,数据库调用只会发生一次,并且只有在之前没有发生时才会发生。
但是,静态类何时“出生”和“被杀”?
是每个用户的会话吗?或者是在Asp.Net应用程序运行时? 当我说用户会话时,我的意思是,每次用户点击某些内容时,都会创建一个新会话,因此,我的静态类会被创建吗?或者静态类对所有其他会话“可见”吗?我希望它仅限于当前用户。
答案 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)
根据我的经验,它是这样的。