埃里克的解决方案是完全有效的,我找到了另一种解决问题的方法,所以我想我会回来把它放在这里,因为我很难找到答案。
诀窍是让实体框架和任何提供程序(如 asp.net Membership/profile/session 等)直接从 Azure 服务配置而不是站点 web.config 文件中读取连接字符串。
对于提供程序,我能够创建继承 System.Web.Providers.DefaultMembershipProvider 类的类并覆盖 Initialize() 方法,然后我使用我编写的帮助程序类来使用 RoleEnvironment.GetConfigurationSettingValue(settingName); 检索连接字符串;调用,它从 Azure 服务配置中读取。
然后我告诉 Membership 提供者使用我的类而不是 DefaultMembershipProvider。这是代码:
网络配置:
<membership defaultProvider="AzureMembershipProvider">
<providers>
<add name="AzureMembershipProvider" type="clientspace.ServiceConfig.AzureMembershipProvider" connectionStringName="ClientspaceDbContext" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
注意自定义提供程序“AzuremembershipProvider”
AzuremembershipProvider 类:
public class AzureMembershipProvider : System.Web.Providers.DefaultMembershipProvider
{
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
string connectionStringName = config["connectionStringName"];
AzureProvidersHelper.UpdateConnectionString(connectionStringName, AzureProvidersHelper.GetRoleEnvironmentSetting(connectionStringName),
AzureProvidersHelper.GetRoleEnvironmentSetting(connectionStringName + "ProviderName"));
base.Initialize(name, config);
}
}
这是帮助类 AzureProvidersHelper.cs:
public static class AzureProvidersHelper
{
internal static string GetRoleEnvironmentSetting(string settingName)
{
try
{
return RoleEnvironment.GetConfigurationSettingValue(settingName);
}
catch
{
throw new ConfigurationErrorsException(String.Format("Unable to find setting in ServiceConfiguration.cscfg: {0}", settingName));
}
}
private static void SetConnectionStringsReadOnly(bool isReadOnly)
{
var fieldInfo = typeof (ConfigurationElementCollection).GetField("bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
if (
fieldInfo != null)
fieldInfo.SetValue(ConfigurationManager.ConnectionStrings, isReadOnly);
}
private static readonly object ConnectionStringLock = new object();
internal static void UpdateConnectionString(string name, string connectionString, string providerName)
{
SetConnectionStringsReadOnly(false);
lock (ConnectionStringLock)
{
ConnectionStringSettings connectionStringSettings = ConfigurationManager.ConnectionStrings["name"];
if (connectionStringSettings != null)
{
connectionStringSettings.ConnectionString = connectionString;
connectionStringSettings.ProviderName = providerName;
}
else
{
ConfigurationManager.ConnectionStrings.Add(new ConnectionStringSettings(name, connectionString, providerName));
}
}
SetConnectionStringsReadOnly(true);
}
}
这里的关键是 RoleEnvironment.GetConfigurationSettingValue 从 Azure 服务配置而不是 web.config 读取。
对于未指定提供程序的实体框架,我必须使用帮助程序类中的 GetRoleEnvironmentSetting() 方法再次将此调用添加到 Global.asax:
var connString = AzureProvidersHelper.GetRoleEnvironmentSetting("ClientspaceDbContext");
Database.DefaultConnectionFactory = new SqlConnectionFactory(connString);
这个解决方案的好处是您最终不必处理 Azure 角色 onstart 事件。
享受
冲刺