全局变量问题
Global variable issue
在我的 web.config 中,我声明了许多基于不同数据库的连接字符串
<add name="connect15-16" connectionString="Initial Catalog=Database15-16;User ID=sa;Password=pwd; "/>
<add name="connect16-17" connectionString="Initial Catalog=Database16-17;User ID=sa;Password=pwd; "/>
<add name="connect17-18" connectionString="Initial Catalog=Database17-18;User ID=sa;Password=pwd; "/>
<add name="connect18-19" connectionString="Initial Catalog=Database18-19;User ID=sa;Password=pwd; "/>
<add name="connect19-20" connectionString="Initial Catalog=Database19-20;User ID=sa;Password=pwd; "/>
登录时,用户必须 select 适当的数据库,然后根据 selected 数据库软件连接到所需的数据库。
我已经创建了一个全局 class,它像这样将用户连接到所需的数据库
public static class Connections
{
public static SqlConnection Connection {get; set;}
public static void Init(string Name)
{
Connection = new SqlConnection(System.Web.Configuration.WebConfigurationManager
.ConnectionStrings[Name].ConnectionString);
}
}
这工作正常。但是当我 运行 它在本地主机上并且多个用户访问它时,主要问题就开始了。
如果 User1 连接到 connect15-16,并且在一段时间后 user2 连接到 connect16-17,则 Connection 变量的值重复并且 User1 连接到 connect16-17
自动地。
我不能为不同的用户使用不同的变量,因为在我的应用程序中的任何地方我都使用这样的连接变量:
Connections.Connection.Open();
Connections.Connection.Close();
Don't create static variable for it, just change your code as follows
public class Connections
{
private SqlConnection Connection { get; set; }
public void Init(string Name)
{
Connection = GetInstance(Name);
}
private SqlConnection GetInstance(string Name)
{
return new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings[Name].ConnectionString);
}
}
If you want to keep it static than you can do it as follows
public class Connections
{
public static SqlConnection Init(string Name)
{
return new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings[Name].ConnectionString);
}
}
Save the SqlConnection Object Returned in a variable for later use
这是静态的正常行为。所以如果你想解决覆盖问题,你需要为不同的用户建立不同的连接。
In ASP.Net, Static variables have application scope and it cannot be
cannot be instantiated. So that it will lead to concurrency issues as
you are facing now. It will be more suitable for windows applications.
如果您需要为单个用户跨页面共享数据,Session 将是您可以访问的最佳选择。它可以帮助您存储和检索用户的值。但在你的情况下 我不会更喜欢会话来存储连接或 connectionString,因为它为攻击者打开了一扇大门。
我想建议对 Connections
class 进行一些修改,以便您可以跨应用程序访问 Connection
。 [假设您在会话中拥有用户名/ID]
public static class Connections
{
private static Dictionary<string, SqlConnection> _Connection = new Dictionary<string, SqlConnection>();
public static Dictionary<string, SqlConnection> Connection
{
get { return _Connection; }
set { _Connection = value; }
}
public static void Init(string Name)
{
string user=HttpContext.Current.Session["UserId"].ToString();
if (!Connection.ContainsKey(user))
{
Connection.Add(user, new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings[Name].ConnectionString));
}
else
{
if (Connection[user] == null)
{
Connection[user] = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings[Name].ConnectionString);
}
}
}
}
使用方法:
让从系统 A
访问的用户 1
的 UserId
为 USR0001
然后调用如下静态方法:
Connections.Init("connect15-16"); // To init the connection
// This will add a connection to the Connection with key USR0001
让从系统 B
访问的用户 2
的 UserId
为 USR0045
然后像下面这样调用静态方法:
Connections.Init("connect16-17"); // To init the connection
// This will add a connection to the Connection with key USR0045
因此,您将获得用户 1 和用户 2 的单独连接。
当您想使用连接时,您可以通过以下代码行访问它们:
SqlConnection sqlCon = Connections.Connection["UserId"]; // this will be different for different users
否则您可以通过这样调用直接访问它们:Connections.Connection["UserId"].Open()
在我的 web.config 中,我声明了许多基于不同数据库的连接字符串
<add name="connect15-16" connectionString="Initial Catalog=Database15-16;User ID=sa;Password=pwd; "/>
<add name="connect16-17" connectionString="Initial Catalog=Database16-17;User ID=sa;Password=pwd; "/>
<add name="connect17-18" connectionString="Initial Catalog=Database17-18;User ID=sa;Password=pwd; "/>
<add name="connect18-19" connectionString="Initial Catalog=Database18-19;User ID=sa;Password=pwd; "/>
<add name="connect19-20" connectionString="Initial Catalog=Database19-20;User ID=sa;Password=pwd; "/>
登录时,用户必须 select 适当的数据库,然后根据 selected 数据库软件连接到所需的数据库。
我已经创建了一个全局 class,它像这样将用户连接到所需的数据库
public static class Connections
{
public static SqlConnection Connection {get; set;}
public static void Init(string Name)
{
Connection = new SqlConnection(System.Web.Configuration.WebConfigurationManager
.ConnectionStrings[Name].ConnectionString);
}
}
这工作正常。但是当我 运行 它在本地主机上并且多个用户访问它时,主要问题就开始了。
如果 User1 连接到 connect15-16,并且在一段时间后 user2 连接到 connect16-17,则 Connection 变量的值重复并且 User1 连接到 connect16-17 自动地。 我不能为不同的用户使用不同的变量,因为在我的应用程序中的任何地方我都使用这样的连接变量:
Connections.Connection.Open();
Connections.Connection.Close();
Don't create static variable for it, just change your code as follows
public class Connections
{
private SqlConnection Connection { get; set; }
public void Init(string Name)
{
Connection = GetInstance(Name);
}
private SqlConnection GetInstance(string Name)
{
return new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings[Name].ConnectionString);
}
}
If you want to keep it static than you can do it as follows
public class Connections
{
public static SqlConnection Init(string Name)
{
return new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings[Name].ConnectionString);
}
}
Save the SqlConnection Object Returned in a variable for later use
这是静态的正常行为。所以如果你想解决覆盖问题,你需要为不同的用户建立不同的连接。
In ASP.Net, Static variables have application scope and it cannot be cannot be instantiated. So that it will lead to concurrency issues as you are facing now. It will be more suitable for windows applications.
如果您需要为单个用户跨页面共享数据,Session 将是您可以访问的最佳选择。它可以帮助您存储和检索用户的值。但在你的情况下 我不会更喜欢会话来存储连接或 connectionString,因为它为攻击者打开了一扇大门。
我想建议对 Connections
class 进行一些修改,以便您可以跨应用程序访问 Connection
。 [假设您在会话中拥有用户名/ID]
public static class Connections
{
private static Dictionary<string, SqlConnection> _Connection = new Dictionary<string, SqlConnection>();
public static Dictionary<string, SqlConnection> Connection
{
get { return _Connection; }
set { _Connection = value; }
}
public static void Init(string Name)
{
string user=HttpContext.Current.Session["UserId"].ToString();
if (!Connection.ContainsKey(user))
{
Connection.Add(user, new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings[Name].ConnectionString));
}
else
{
if (Connection[user] == null)
{
Connection[user] = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings[Name].ConnectionString);
}
}
}
}
使用方法:
让从系统 A
访问的用户 1
的 UserId
为 USR0001
然后调用如下静态方法:
Connections.Init("connect15-16"); // To init the connection
// This will add a connection to the Connection with key USR0001
让从系统 B
访问的用户 2
的 UserId
为 USR0045
然后像下面这样调用静态方法:
Connections.Init("connect16-17"); // To init the connection
// This will add a connection to the Connection with key USR0045
因此,您将获得用户 1 和用户 2 的单独连接。
当您想使用连接时,您可以通过以下代码行访问它们:
SqlConnection sqlCon = Connections.Connection["UserId"]; // this will be different for different users
否则您可以通过这样调用直接访问它们:Connections.Connection["UserId"].Open()