使用唯一的Sql Azure连接字符串封装和发布Azure云服务



我有一个带有Azure云服务项目和单个webrole的。net Web解决方案。我将它部署到东海岸和西海岸的数据/计算中心,用于故障转移目的,并要求使用Powershell MSBuild和Jenkins自动部署。

问题是我需要在Web中更改Sql Azure数据库connectionString。在打包和发布到每个部署之前配置。看起来很简单。

我理解webrole属性设置选项卡允许您使用"字符串"或"连接字符串"类型向每个部署添加自定义配置属性,但看起来"连接字符串"选项仅适用于Blob,表或队列存储。如果我使用"字符串"并给它一个Sql Azure连接字符串类型,它写出来作为一个键/值对和实体框架和成员资格提供程序找不到它。

是否有一种方法可以添加指向Sql Azure的每个部署连接字符串设置?

谢谢,大卫

Erick的解决方案是完全有效的,我找到了另一种解决问题的方法,所以我想我应该回来把它放在这里,因为我很难找到答案。

诀窍是获得实体框架和任何提供者,如asp.net会员/配置文件/会话等…直接从Azure服务配置而不是从站点web读取连接字符串。配置文件。

对于提供程序,我可以创建继承System.Web.Providers.DefaultMembershipProvider类的类,并覆盖Initialize()方法,然后使用我编写的辅助类使用RoleEnvironment.GetConfigurationSettingValue(settingName)检索连接字符串;

从Azure服务配置中读取。

然后告诉会员资格提供者使用我的类而不是DefaultMembershipProvider。下面是代码:

web . config:

<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);
    }
}

这里的关键是角色环境。GetConfigurationSettingValue从Azure服务配置中读取,而不是从web.config中读取。

对于没有指定提供者的实体框架,我必须将此调用添加到全局。再次使用来自帮助类的GetRoleEnvironmentSetting()方法:

var connString = AzureProvidersHelper.GetRoleEnvironmentSetting("ClientspaceDbContext");
        Database.DefaultConnectionFactory = new SqlConnectionFactory(connString);

这个解决方案的好处是,你最终不必处理Azure角色onstart事件。

享受

dnash

David,

一个好的选择是使用Azure配置。如果右键单击Azure项目,可以添加额外的配置。将您的连接字符串放入正确的配置中(例如,servicecconfiguration . westcoast)。cscfg ServiceConfiguration.EastCoast。cscfg等等)。

在构建脚本中,将TargetProfile属性与配置名称一起传递给MSBuild,这些设置将被构建到最终的cscfg中。

如果你遇到任何问题,请告诉我。我做了这个方法,我试了几次才让它正常工作。一些细节可能会有帮助。

埃里克

相关内容

  • 没有找到相关文章

最新更新