如何在服务栈中动态更改sql server连接字符串
本文关键字:sql server 连接 字符串 动态 服务 | 更新日期: 2023-09-27 17:54:41
我正在做Asp。. Net MVC和ServiceStack。我试图连接到sql server数据库使用servicestack或mlite。像
var connectionString = ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString;
container.Register<IDbConnectionFactory>(
new OrmLiteConnectionFactory(connectionString,
SqlServerOrmLiteDialectProvider.Instance)
{
ConnectionFilter = x => new ProfiledDbConnection(x, Profiler.Current)
});
我能够连接到数据库,但在我的情况下,我需要动态地改变连接字符串。这意味着我需要从请求体读取内容,并准备一个连接字符串。在servicestack中,我们在AppHost类中配置sql server连接字符串,意思是在应用程序启动时。但我需要设置连接字符串在我的控制器。我试过把它放在会话中,并在ClassLibrary servicebase类中使用该会话。但是我不能使用asp。类库中的Net会话。如何在服务栈中动态更改sql server连接字符串。
我会将IDbConnectionFactory
更改为在请求范围内重用,而不是当前的默认值,它在所有请求之间共享。我还创建了一个静态方法(GetDatabaseConnectionFactory()
),它将OrmLiteConnectionFactory
的实例返回到具有自定义连接字符串的IoC容器。
为了确定连接字符串,我使用了一个请求过滤器,它只是读取参数connectionstring
。如果没有设置,它将使用默认值。这个值是设置在RequestContext.Items
集合中,可以通过GetDatabaseConnectionFactory()
方法访问。
记住,以这种方式暴露连接字符串是危险的,总是彻底检查任何连接字符串值,以确保它们不包含恶意值。。确保它们不尝试连接到管理数据库,或不同的服务器,或更改默认设置覆盖等。
在你的AppHost:
ServiceStack V3:
public override void Configure(Container container)
{
container.Register<IDbConnectionFactory>(c => GetDatabaseConnectionFactory()).ReusedWithin(ReuseScope.Request);
RequestFilters.Add((req,res,obj) => {
// Default value
var defaultConnectionString = ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString;
// Get the connection string from the connectionstring parameter, or use default
var dbConnectionString = req.GetParam("connectionstring") ?? defaultConnectionString;
// You should perform some checks here to make sure the connectionstring isn't something it shouldn't be
// ...
// Save the connection string to the HostContext.Instance.Items collection, so we can read it later
HostContext.Instance.Items.Add("ConnectionString", dbConnectionString);
});
}
public static IDbConnectionFactory GetDatabaseConnectionFactory()
{
// Read the connection string from our HostContext Items
var dbConnectionString = HostContext.Instance.Items["ConnectionString"];
if(dbConnectionString == null)
throw new Exception("Connection string has not been set");
// Return the connection factory for the given connection string
return new OrmLiteConnectionFactory(dbConnectionString, SqlServerOrmLiteDialectProvider.Instance) {
ConnectionFilter = x => new ProfiledDbConnection(x, Profiler.Current)
});
}
Usings:
using System;
using Funq;
using ServiceStack.ServiceInterface;
using ServiceStack.ServiceHost;
using ServiceStack.WebHost.Endpoints;
using ServiceStack.OrmLite;
using ServiceStack.Common;
ServiceStack V4:
public override void Configure(Container container)
{
container.Register<IDbConnectionFactory>(c => GetDatabaseConnectionFactory()).ReusedWithin(ReuseScope.Request);
GlobalRequestFilters.Add((req,res,obj) => {
// Default value
var defaultConnectionString = ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString;
// Get the connection string from the connectionstring parameter, or use default
var dbConnectionString = req.GetParam("connectionstring") ?? defaultConnectionString;
// You should perform some checks here to make sure the connectionstring isn't something it shouldn't be
// ...
// Save the connection string to the RequestContext.Items collection, so we can read it later
HostContext.RequestContext.Items.Add("ConnectionString", dbConnectionString);
});
}
public static IDbConnectionFactory GetDatabaseConnectionFactory()
{
// Read the connection string from our Items
var dbConnectionString = HostContext.RequestContext.Items["ConnectionString"];
if(dbConnectionString == null)
throw new Exception("Connection string has not been set");
// Return the connection factory for the given connection string
return new OrmLiteConnectionFactory(dbConnectionString, SqlServerOrmLiteDialectProvider.Instance) {
ConnectionFilter = x => new ProfiledDbConnection(x, Profiler.Current)
});
}
Usings:
using System;
using Funq;
using ServiceStack;
using ServiceStack.Data;
using ServiceStack.OrmLite;
using ServiceStack.OrmLite.Sqlite;