I am trying to Initialize SQL Membership Provider by code and everything is working fine in the first request only!. When the code below executes again (after refreshing the page for example) I get the following error:
The attribute 'connectionStringName' is missing or empty.
Page Load Code:
MembershipSection membershipSection = (MembershipSection)ConfigurationManager.GetSection("system.web/membership");
string sqlProviderName = "AspNetSqlMembershipProvider";
NameValueCollection providerConfig;
providerConfig = membershipSection.Providers[sqlProviderName].Parameters; // returning empty list in the second request
var _SqlProvider = new SqlMembershipProvider();
_SqlProvider.Initialize(sqlProviderName, providerConfig);
Web.config:
<membership defaultProvider="AspNetSqlMembershipProvider">
<providers>
<clear />
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ConnectionString" enablePasswordRetrieval="true" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" passwordFormat="Encrypted" maxInvalidPasswordAttempts="5" passwordAttemptWindow="10" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" applicationName="/" />
</providers>
</membership>
Any Advice?
how about just keep your data/connectionstring/obj at static level (as like singleton)?
it's not like connectionstring is going to be change throughout the web instance, does it?
static string/dataType _DataToBeRead1timeOnly = null;
static string/dataType DataToBeRead1timeOnly
{
get {
if (_DataToBeRead1timeOnly == null) { _DataToBeRead1timeOnly = .... }
return _DataToBeRead1timeOnly;
}
}
Related
Hi I want Change Text of error requiresUniqueEmail
i set requiresUniqueEmail provider to true
and massage default is The e-mail address that you entered is already in use. Please enter a different e-mail address
and i want change that text
my provide is
<add name="MemberShipProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="******"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
applicationName="/"
requiresUniqueEmail="true"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="5"
minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10"
passwordStrengthRegularExpression="" />
I'm not positive this will work with SqlMembershipProvider but I've used this with the built-in sign up control:
protected void RegisterUser_CreateUserError(object sender, CreateUserErrorEventArgs e)
{
switch(e.CreateUserError)
{
case MembershipCreateStatus.DuplicateUserName:
RegisterUser.DuplicateUserNameErrorMessage = "No can do!";
break;
// other cases.
default:
break;
}
}
I want to change a value is my app.config dynamically from my project.
This is my app.config:
<?xml version="1.0"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<system.web>
<membership defaultProvider="SqlProvider">
<providers>
<clear />
<add name="SqlProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="MySqlConnection"
enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false"
applicationName="app1" requiresUniqueEmail="false"
passwordFormat="Hashed" maxInvalidPasswordAttempts="6545"
minRequiredPasswordLength="4" minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10" passwordStrengthRegularExpression=""/>
</providers>
</membership>
</system.web>
</configuration>
I want to change the value of 'applicationName' key inside the 'sqlProvider'.
All i could find on the net is people using:
ConfigurationManager.AppSettings["key"]
But this doesnt work for me.
ConfigurationManager.AppSettings["key"] usually works with the setting defined under "AppSettings" section. you may try out the following code-
public class MembershipSetting
{
/// <summary>
/// Gets or sets the name of the setting.
/// </summary>
public string SettingName { get; set; }
/// <summary>
/// Gets or sets the setting value.
/// </summary>
public string SettingValue { get; set; }
}
private List<MembershipSetting> GetMembershipSetting()
{
List<MembershipSetting> settings = new List<MembershipSetting>
{
new MembershipSetting {SettingName = "Dafult Membership Provider", SettingValue = Membership.Provider.ToString() },
new MembershipSetting {SettingName = "Minimum Required Password Length", SettingValue = Membership.MinRequiredPasswordLength.ToString(CultureInfo.InvariantCulture) },
new MembershipSetting {SettingName = "Minimum Required Non Alphanumeric Characters",SettingValue = Membership.MinRequiredNonAlphanumericCharacters.ToString(CultureInfo.InvariantCulture)},
new MembershipSetting {SettingName = "Password reset enabled", SettingValue = Membership.EnablePasswordReset.ToString()},
new MembershipSetting {SettingName = "Maximum Invalid Password Attempts",SettingValue = Membership.MaxInvalidPasswordAttempts.ToString(CultureInfo.InvariantCulture) },
new MembershipSetting {SettingName = "Attempt windows",SettingValue = Membership.PasswordAttemptWindow.ToString(CultureInfo.InvariantCulture)},
new MembershipSetting {SettingName = "applicationName",SettingValue = Membership.ApplicationName.ToString(CultureInfo.InvariantCulture)}
};
return settings;
}
This article is originally posted here.
I have the following code, which I want to use to modify the ProfileBase connectionString:
ProfileBase profile = ProfileBase.Create(username);
string _connectionString = (_DataModel.Connection as System.Data.EntityClient.EntityConnection).StoreConnection.ConnectionString;
FieldInfo connectionStringField = profile.Providers["MySqlProfileProvider"].GetType().BaseType.GetField("_sqlConnectionString", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
connectionStringField.SetValue(profile.Providers["MySqlProfileProvider"], _connectionString);
profile["FirstName"] = firstName;
profile["Surname"] = surname;
profile.Save();
First of all the connectionStringField always comes back as null, however I can see that profile.Providers does contain MySqlProfileProvider. This is specified within my Web.Config:
<profile defaultProvider="MySqlProfileProvider">
<providers>
<clear/>
<add name="MySqlProfileProvider" connectionStringName="MyApp" applicationName="MyApp" type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</providers>
<properties>
<add allowAnonymous="false" defaultValue="" name="FirstName" readOnly="false" serializeAs="String" type="System.String"/>
<add allowAnonymous="false" defaultValue="" name="Surname" readOnly="false" serializeAs="String" type="System.String"/>
</properties>
</profile>
My question is how come connectionStringField is coming back as null? Does this mean I cannot modify the connection string like I normally would with a custom MembershipProvider by overriding its Initialize method?
You went one too many basetypes down:
.Providers["MySqlProfileProvider"].GetType()**.BaseType**.GetField
.Providers["MySqlProfileProvider"].GetType().GetField
The following code should work:
string _connectionString = (_DataModel.Connection as System.Data.EntityClient.EntityConnection).StoreConnection.ConnectionString;
Type type = profile.Providers["MySqlProfileProvider"].GetType();
FieldInfo connectionStringField = type.GetField("_sqlConnectionString", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
connectionStringField.SetValue(profile.Providers["MySqlProfileProvider"], _connectionString);
I'm trying to use the MySQLRoleProvider(MySql.Web, Version=6.2.2.0) with Visual Web Developer 2008.
When trying to add a role I get an exception "Table 'test.my_aspnet_applications' doesn't exist"
if (!Roles.RoleExists("TestRole"))
{
Roles.CreateRole("TestRole");
}
Can someone tell me where I went wrong. Or tell me how to generate / find the correct database script to create the role, membership, profile ... MySql tables.
<membership defaultProvider="MySQLMembershipProvider">
<providers>
<remove name="MySQLMembershipProvider"/>
<add autogenerateschema="true" connectionStringName="LocalMySqlServer" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" applicationName="/" requiresUniqueEmail="false" passwordFormat="Clear" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="1" passwordAttemptWindow="10" passwordStrengthRegularExpression="" name="MySQLMembershipProvider" type="MySql.Web.Security.MySQLMembershipProvider, MySql.Web, Version=6.2.2.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"/>
</providers>
</membership>
<profile enabled="true" defaultProvider="MySQLProfileProvider">
<providers>
<remove name="MySQLProfileProvider"/>
<add name="MySQLProfileProvider" autogenerateschema="true" type="MySql.Web.Profile.MySQLProfileProvider, MySql.Web, Version=6.2.2.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" connectionStringName="LocalMySqlServer" applicationName="/"/>
</providers>
</profile>
<roleManager enabled="true" defaultProvider="MySQLRoleProvider">
<providers>
<remove name="MySQLRoleProvider"/>
<add autogenerateschema="true" connectionStringName="LocalMySqlServer" applicationName="/" name="MySQLRoleProvider" type="MySql.Web.Security.MySQLRoleProvider, MySql.Web, Version=6.2.2.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"/>
</providers>
</roleManager>
Have you used the ASP.Net configuration tool to switch your application's provider to the MySQL provider? I believe this is what triggers the MySQL provider to automatically generate the schema.
Follow this codeproject howto and you'll be fine.
If your database won't generate try this:
Create a custom ContextInitializer and add this to the Global.asax:
Database.SetInitializer(new CreateMySqlDatabaseIfNotExists<MyContext>());
internal class CreateMySqlDatabaseIfNotExists<TContext>: IDatabaseInitializer<TContext> where TContext : MyContext
{
public void InitializeDatabase(TContext context)
{
if (context.Database.Exists())
{
if (!context.Database.CompatibleWithModel(false))
throw new InvalidOperationException("The model has changed!");
}
else
{
CreateMySqlDatabase(context);
Seed(context);
}
}
private void CreateMySqlDatabase(TContext context)
{
try
{
context.Database.Create();
return;
}
catch (MySqlException ex)
{
// Ignore the parse exception
if (ex.Number != 1064)
{
throw;
}
}
// Manually create the metadata table
using (var connection = ((MySqlConnection) context
.Database.Connection).Clone())
using (var command = connection.CreateCommand())
{
command.CommandText =
#"
CREATE TABLE __MigrationHistory (
MigrationId mediumtext NOT NULL,
CreatedOn datetime NOT NULL,
Model mediumblob NOT NULL,
ProductVersion mediumtext NOT NULL);
ALTER TABLE __MigrationHistory
ADD PRIMARY KEY (MigrationId(255));
INSERT INTO __MigrationHistory (
MigrationId,
CreatedOn,
Model,
ProductVersion)
VALUES (
'InitialCreate',
#CreatedOn,
#Model,
#ProductVersion);
";
command.Parameters.AddWithValue(
"#Model",
GetModel(context));
command.Parameters.AddWithValue(
"#ProductVersion",
GetProductVersion());
command.Parameters.AddWithValue(
"#CreatedOn",
DateTime.Now);
connection.Open();
command.ExecuteNonQuery();
}
}
private byte[] GetModel(TContext context)
{
using (var memoryStream = new MemoryStream())
{
using (var gzipStream = new GZipStream(
memoryStream,
CompressionMode.Compress))
using (var xmlWriter = XmlWriter.Create(
gzipStream,
new XmlWriterSettings {Indent = true}))
{
EdmxWriter.WriteEdmx(context, xmlWriter);
}
return memoryStream.ToArray();
}
}
private string GetProductVersion()
{
return typeof (DbContext).Assembly
.GetCustomAttributes(false)
.OfType<AssemblyInformationalVersionAttribute>()
.Single()
.InformationalVersion;
}
protected void Seed(TContext context)
{ // ...
context.SaveChanges();
}
}
I have an asp.net web app that uses forms-based authentication, a SqlMembershipProvider (using an encrypted password format), and a SqlRoleProvider. I need to know if it's possible to administer the users (create new users, assign them to roles, etc.) from a windows application - the powers that be don't want any administrative functionality in the web app itself.
Here is the membership provider definition from web.config:
<membership defaultProvider="MyProvider">
<providers>
<add name="MyProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="MyConnectionString"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
applicationName="/MyWebApp"
requiresUniqueEmail="true"
passwordFormat="Encrypted"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="1"
passwordAttemptWindow="10"
passwordStrengthRegularExpression=""/>
</providers>
</membership>
And the role manager definition:
<roleManager enabled="true" defaultProvider="MyRoleManager">
<providers>
<add name="MyRoleManager"
type="System.Web.Security.SqlRoleProvider"
connectionStringName="MyConnectionString"
applicationName="/MyWebApp" />
</providers>
</roleManager>
And here is the machineKey definition (necessary to be able to use encrypted passwords):
<machineKey
validationKey="BC50A82A6AF6A015C34C7946D29B817C00F04D2AB10BC2128D1E2433D0E365E426E57337CECAE9A0681A2C736B9779B42F75D60F09F142C60E9E0E8F9840DB46"
decryptionKey="122035576C5476DCD8F3611954C837CDA5FE33BCDBBF23F7"
validation="SHA1"
decryption="AES"/>
So, obviously, I have a Sql Server database that contains the users and roles for the web app. I'd like to create a separate windows app that references the web app assembly, and use the configured MembershipProvider, RoleProvider, and machineKey to create users, assign users to roles, etc. If that's not possible, I can duplicate the configuration settings from web.config within the windows app. But I don't know how to do this either.
Am I way out of line thinking that this is possible? I've tried googling for a solution, but the signal-to-noise ratio is really bad.
Some options:
You could use the Web Site
Administration Tool, which isn't
Windows-Forms-based, but isn't part
of your Web app, either. It comes
with Visual Studio and can be
accessed by clicking the ASP.NET
Configuration icon in the Solution
Explorer.
It's possible to directly manipulate
the provider database used by a
SqlMembershipProvider from a Windows
Forms app, but you might have to be
careful not to break things.
If you were to create a custom
membership provider, you'd be in
control of how membership and role
data is persisted. If you did that
you could create a reusable library
that could be used in the Web app and
a Windows Forms app, too.
I don't think trying to use a SqlMembershipProvider from a Windows Forms app is a practical approach.
I've come up with a solution, based on the other answers (who both got +1), and some other sites out there.
First, I created Application Config file (app.config). It mirrors exactly what is found in web.config from the web app, with the exception of how the connection string was handled:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="connectionStrings" type="System.Configuration.ConnectionStringsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="MyConnectionString"
connectionString ="SERVER=abc;UID=def;PWD=hij;Initial Catalog=klm;MultipleActiveResultsets=True"/>
</connectionStrings>
<system.web>
<membership defaultProvider="MySqlMembershipProvider">
<providers>
<add name="MySqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="MyConnectionString"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
applicationName="/MyWebApp"
requiresUniqueEmail="true"
passwordFormat="Encrypted"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="1"
passwordAttemptWindow="10"
passwordStrengthRegularExpression=""/>
</providers>
</membership>
<roleManager enabled="true" defaultProvider="MySqlRoleManager">
<providers>
<add name="MySqlRoleManager"
type="System.Web.Security.SqlRoleProvider"
connectionStringName="MyConnectionString"
applicationName="/MyWebApp" />
</providers>
</roleManager>
<machineKey
validationKey="BC50A82A6AF6A015C34C7946D29B817C00F04D2AB10BC2128D1E2433D0E365E426E57337CECAE9A0681A2C736B9779B42F75D60F09F142C60E9E0E8F9840DB46"
decryptionKey="122035576C5476DCD8F3611954C837CDA5FE33BCDBBF23F7"
validation="SHA1"
decryption="AES"/>
</system.web>
</configuration>
Then I created a helper class that provides access to two singletons: a MembershipProvider and a RoleProvider. This turned out to be easier than I thought, once I knew how to do it:
using System.Configuration;
using System.Reflection;
using System.Web.Security;
namespace WebAdminViaWindows
{
internal static class Provider
{
private static readonly string assemblyFilePath = Assembly.GetExecutingAssembly().Location;
static Provider()
{
Membership = CreateMembershipProvider();
Role = CreateRoleProvider();
}
public static MembershipProvider Membership { get; private set; }
public static RoleProvider Role { get; private set; }
private static MembershipProvider CreateMembershipProvider()
{
var config = ConfigurationManager.OpenExeConfiguration(assemblyFilePath);
var systemWebGroup = config.SectionGroups["system.web"];
if (systemWebGroup == null)
{
throw new ConfigurationErrorsException("system.web group not found in configuration");
}
var membershipSection = systemWebGroup.Sections["membership"];
if (membershipSection == null)
{
throw new ConfigurationErrorsException("membership section not found in system.web group");
}
var defaultProviderProperty = membershipSection.ElementInformation.Properties["defaultProvider"];
if (defaultProviderProperty == null)
{
throw new ConfigurationErrorsException("defaultProvider property not found in membership section");
}
var defaultProviderName = defaultProviderProperty.Value as string;
if (defaultProviderName == null)
{
throw new ConfigurationErrorsException("defaultProvider property is not a string value");
}
var providersProperty = membershipSection.ElementInformation.Properties["providers"];
if (providersProperty == null)
{
throw new ConfigurationErrorsException("providers property not found in membership section");
}
var providerCollection = providersProperty.Value as ProviderSettingsCollection;
if (providerCollection == null)
{
throw new ConfigurationErrorsException("providers property is not an instance of ProviderSettingsCollection");
}
ProviderSettings membershipProviderSettings = null;
foreach (ProviderSettings providerSetting in providerCollection)
{
if (providerSetting.Name == defaultProviderName)
{
membershipProviderSettings = providerSetting;
}
}
if (membershipProviderSettings == null)
{
if (providerCollection.Count > 0)
{
membershipProviderSettings = providerCollection[0];
}
else
{
throw new ConfigurationErrorsException("No providers found in configuration");
}
}
var provider = new SqlMembershipProvider();
provider.Initialize("MySqlMembershipProvider", membershipProviderSettings.Parameters);
return provider;
}
private static RoleProvider CreateRoleProvider()
{
var config = ConfigurationManager.OpenExeConfiguration(assemblyFilePath);
var systemWebGroup = config.SectionGroups["system.web"];
if (systemWebGroup == null)
{
throw new ConfigurationErrorsException("system.web group not found in configuration");
}
var roleManagerSection = systemWebGroup.Sections["roleManager"];
if (roleManagerSection == null)
{
throw new ConfigurationErrorsException("roleManager section not found in system.web group");
}
var defaultProviderProperty = roleManagerSection.ElementInformation.Properties["defaultProvider"];
if (defaultProviderProperty == null)
{
throw new ConfigurationErrorsException("defaultProvider property not found in roleManager section");
}
var defaultProviderName = defaultProviderProperty.Value as string;
if (defaultProviderName == null)
{
throw new ConfigurationErrorsException("defaultProvider property is not a string value");
}
var providersProperty = roleManagerSection.ElementInformation.Properties["providers"];
if (providersProperty == null)
{
throw new ConfigurationErrorsException("providers property not found in roleManagerSection section");
}
var providerCollection = providersProperty.Value as ProviderSettingsCollection;
if (providerCollection == null)
{
throw new ConfigurationErrorsException("providers property is not an instance of ProviderSettingsCollection");
}
ProviderSettings roleProviderSettings = null;
foreach (ProviderSettings providerSetting in providerCollection)
{
if (providerSetting.Name == defaultProviderName)
{
roleProviderSettings = providerSetting;
}
}
if (roleProviderSettings == null)
{
if (providerCollection.Count > 0)
{
roleProviderSettings = providerCollection[0];
}
else
{
throw new ConfigurationErrorsException("No providers found in configuration");
}
}
var provider = new SqlRoleProvider();
provider.Initialize("MySqlRoleManager", roleProviderSettings.Parameters);
return provider;
}
}
}
At this point all that's needed is to access the Membership and Role properties of the Provider class. As an example, the following prints out the first 10 users and their roles:
int total;
foreach (MembershipUser user in Provider.Membership.GetAllUsers(0, 10, out total))
{
var sb = new StringBuilder();
sb.AppendLine(user.UserName);
foreach (var role in Provider.Role.GetRolesForUser(user.UserName))
{
sb.AppendLine("\t" + role);
}
Console.WriteLine(sb.ToString());
}
I'm not sure what "best-practice" would be here, but a simple way that should work is this.
Make a new windows app
Add an Application Config file
(app.config)
Copy the appropriate settings into
the app.config (settings from above
^)
Add a reference to System.Web
And copy the code from your web app
that uses the above settings to
connect to the database
That should do what you want.