Я пытаюсь перейти на Azure (включая SQL Azure) с мультитенантным приложением ASP.NET MVC.Каждый клиент получает свою собственную базу данных, которая включает в себя все свои учетные данные.
Мы можем установить строку подключения для SqlMembershipProvider при инициализации объекта SqlMembershipProvider.Однако последующие запросы к другим поддоменам (в одном сеансе) не изменяют строку подключения.Я нашел пример, в котором реализация переопределяет SqlMembershipProviders ConnectionString, но это невозможно в версии 4.0 библиотеки System.Web.
Мы могли бы создать единую базу данных о членстве и проходить аутентификацию на этом основании ... но мы хотели бы сохранить учетные данные клиентов в этой модели SAAS.
Поэтому вопрос заключается в том, какЯ изменяю строку подключения SQLMembershipProviders динамически для каждого запроса?
Web.config
<membership defaultProvider="TenantMembershipProvider">
<providers>
<clear/>
<add name="TenantMembershipProvider" type="ABC.Infrastructure.MultiTenancy.TenantMembershipProvider, ABC"
connectionStringName="ApplicationServices" enablePasswordRetrieval="true" enablePasswordReset="true" requiresQuestionAndAnswer="false"
requiresUniqueEmail="false" passwordFormat="Clear" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6"
minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" applicationName="/"/>
</providers>
</membership>
TenantMembershipProvider.cs, который обрабатывает инициализацию
public class TenantMembershipProvider : SqlMembershipProvider
{
private SiteLinqSession _session;
private MasterSession _masterSession;
private static readonly Dictionary<string, Customer> _customers = new Dictionary<string, Customer>();
private static string _host;
public override void Initialize(string name, NameValueCollection config)
{
base.Initialize(name, config);
string connectionString = GetConnectionString();
FieldInfo connectionStringField = GetType().BaseType.GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);
connectionStringField.SetValue(this, connectionString);
}
private string GetConnectionString()
{
var headers = HttpContext.Current.Request.Headers["Host"];
string[] host = headers.Split('.');
_host = host[0];
if (_host == "127") _host = "demo";
var customer = GetSite(_host);
return BuildTenantConnectionString(customer.ConnectionSetting);
}
private Customer GetSite(string host)
{
Customer customer;
//check dictionary if customer exists for the subdomain
_customers.TryGetValue(host, out customer);
if (customer != null)
return customer;
//if not get the customer record and add it to the dictionary
_masterSession = new MasterSession();
var customers = _masterSession.All<Customer>();
customer = customers.SingleOrDefault(x => x.SubDomain == _host);
if (customer != null)
_customers.Add(host, customer);
return customer;
}
private string BuildTenantConnectionString(ConnectionSetting setting)
{
return string.Format("Data Source={0};Initial Catalog={1};User Id={2};Password={3};", setting.DataSource, setting.Catalog, setting.Username, setting.Password);
}
}