Я собираюсь рискнуть этим как ответом, потому что я действительно не вижу потребности в том, что вы описываете:
Если строка подключения уже зашифрована в файле web.config * _you_dont_need_to_decrypt_it * при запуске приложения, вы просто расшифровываете его каждый раз, когда создаете экземпляр подключения к базе данных. Поверьте, производительность дешифрования строки подключения незначительна, даже если вы делаете это каждый раз, когда открываете соединение. Но если предположить, что вы помешаны на производительности и хотите расшифровать его только один раз и вставить в сеанс (плохая идея, но, похоже, именно это вы и делаете), вам не о чем беспокоиться, как я объясню в пункте 3 ниже.
Предположим, что вы расшифровали его один раз (Application_Start, что у вас есть), почему вы говорите, что вам нужно зашифровать его снова before application closes - by whatever way - either normal close or application error.
? Строка подключения не передается по проводам, это то, что используется на серверной стороне для создания экземпляра соединения с базой данных, но это не то, что кто-то может увидеть по используя приложение, если, конечно, вы храните его во ViewState, но это было бы очень глупо.
Вы упомянули, что что-то храните в сеансе, хотя неясно на 100%, ссылаетесь ли вы на строку подключения или что-то еще. Предполагая, что это строка подключения (опять же, я не могу придумать вескую причину для этого. Приношу извинения, если она есть.) Это не то, что может увидеть любой пользователь, так как Session - это всего лишь байты памяти на сервере . То же самое относится и к кешу.
Так вот и все.
Вы дешифруете строку подключения, создаете экземпляр подключения, делаете свое дело и закрываете подключение. Строка соединения может оставаться зашифрованной в web.config навсегда; нетронутый.
UPDATE
Поскольку OP использует провайдера членства, решение состоит в том, чтобы внедрить вашего собственного провайдера членства. Вы можете скачать пример проекта, демонстрирующего, как это сделать от Microsoft, по следующей ссылке: http://download.microsoft.com/download/a/b/3/ab3c284b-dc9a-473d-b7e3-33bacfcc8e98/ProviderToolkitSamples.msi
Посмотрите на SQLConnectionHelper.cs
класс.
Вот еще один пост , делающий в точности то, что вам нужно.
ОБНОВЛЕНИЕ 2
Вот еще один способ сделать то же самое, используя Reflection. Назовите это хаком, но, похоже, он справится с работой:
Внутри Application_PreRequestHandler
в Global.asax
вызовите этот метод, где connectionString
- расшифрованная строка вашего соединения:
private void SetProviderConnectionString(string connectionString)
{
// Set private property of Membership, Role and Profile providers. Do not try this at home!!
var connectionStringField = Membership.Provider.GetType().GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);
if (connectionStringField != null)
connectionStringField.SetValue(Membership.Provider, connectionString);
var roleField = Roles.Provider.GetType().GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);
if (roleField != null)
roleField.SetValue(Roles.Provider, connectionString);
var profileField = ProfileManager.Provider.GetType().GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);
if (profileField != null)
profileField.SetValue(ProfileManager.Provider, connectionString);
}
Источник.