Integrating Simple Authentication with Existing database using Model First
Trying to learn the new things in MVC 4 I wanted to work with Simple Authentication so that’s the curve for today .
Since there is some love lost between me and Code First I wanted to try it out with one of the databases I already have and keep it simple. I tried to follow the different long blogs out there how to do it and I was hoping all would go smooth and fine but before long I was stack with the error “Unable to find the requested .NET Framework Data Provider” when I call
WebSecurity.InitializeDatabaseConnection()
So if you are here with the same error without further due let me tell u what is wrong.
Under ur class
InitializeSimpleMembershipAttribute
the method
SimpleMembershipInitializer()
and the line of code
WebSecurity.InitializeDatabaseConnection
is throwing the exception and the problem is WebSecurity.InitializeDatabaseConnection method cann’t use connection string with
System.Data.EntityClient
which is used when we are using the model first paradigm.
So what’s the solution?
Well a solution can be to create another connection string meant to be for Websecurity purpose with
providerName="System.Data.SqlClient".
Don’t worry I amn’t gone leave you just like that lets me show you how I did it follow my lead. For the sake of simplicity I have just created a simple Internet application. Which will have all the Account related models and controllers and pages.
The following are the class’s that will be added for you by default
•\Models\AccountModels.cs defines a basic user account and includes data annotations to define keys and such
•\Filters\InitializeSimpleMembershipAttribute.cs creates the membership database using the above model, then calls WebSecurity.InitializeDatabaseConnection which verifies that the underlying tables are in place and marks initialization as complete (for the application’s lifetime)
•\Models\AccountModels.cs defines a basic user account and includes data annotations to define keys and such
•\Filters\InitializeSimpleMembershipAttribute.cs creates the membership database using the above model, then calls WebSecurity.InitializeDatabaseConnection which verifies that the underlying tables are in place and marks initialization as complete (for the application’s lifetime)
“With SimpleMembership it was decided that it was easier to allow you, the developer, to have control of the users table and let SimpleMembership handle storing the authentication credentials. For example, you might already have a users table and want to integrate it with SimpleMembership. All SimpleMembership requires is that there are two columns on your users table so that we can hook up to it – an “ID” column and a “username” column. The important part here is that they can be named whatever you want. For instance username doesn’t have to be an alias it could be an email column you just have to tell SimpleMembership to treat that as the “username” used to log in.” Matthew M.Osborn
Since a great deal of control is given to us on the user table I just wanted to use my already existing database and just create a table called user with id and username columns.
Now go to your web.config file and look for you connection strings. You will have two connection strings
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-Membership-20130118230532;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-Membership-20130118230532.mdf" providerName="System.Data.SqlClient" /> <add name="TestMembershipEntities" connectionString="metadata=res://*/Models.DBModel.csdl|res://*/Models.DBModel.ssdl|res://*/Models.DBModel.msl;provider=System.Data.SqlClient;provider connection string="data source=ICECOOL-PC\MYINSTANCE;initial catalog=TestMembership;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" /></connectionStrings>
The First connection string is the connection string that’s created by default when u created the project and its created to handle your web security features. If the database doesn’t exist it will be generated during our first run.
The Second connection is the connection string to my existing database and if you pay attention you can see that providers for the two are different. Since we want our Authentication activities to be handled with our existing database lets delete or comment out the first connection string. After deleting the first connection string add a connection string to the same database as the second connection string but this time with appropriate provider that is System.Data.SqlClient.
<add name="ConnStringForWebSecurity" connectionString="data source=ICECOOL-PC\MyInstance;Initial Catalog=TestMembership;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
| Before |
|---|
public class UsersContext : DbContext { public UsersContext() : base("DefaultConnection") { } public DbSet<UserProfile> UserProfiles { get; set; } } |
| After |
public class UsersContext : TestMembershipEntities { public UsersContext() { } } |
| Before |
[Table("UserProfile")] public class UserProfile { [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int UserId { get; set; } public string UserName { get; set; } } |
| After |
// comment or delete this code /* [Table("UserProfile")] public class UserProfile { [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int UserId { get; set; } public string UserName { get; set; } }*/ |
Next go to Models and AccountModels.cs and change your Inheritance to TestMembershipEntities or the Entity that is you defined and then Delete the Code First class defined in there and also change the decorator of you constructor method and the property defined in it.
Two more thing to do ; go to Filters/InitializeSimpleMembershipAttribute.cs and go to SimpleMembershipInitializer class and replace the code as follows. What we did below is comment out code we wont be using and since we are using model first and we have the table and also change the connection string parameter for the WebSecurity.InitializeDatabaseConnection method and the table name and column name it expects as per our table definition.
| Before |
|---|
private class SimpleMembershipInitializer { public SimpleMembershipInitializer() { Database.SetInitializer<UsersContext>(null); try { using (var context = new UsersContext()) { if (!context.Database.Exists()) { // Create the SimpleMembership database without Entity Framework migration schema ((IObjectContextAdapter)context).ObjectContext.CreateDatabase(); } } WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true); } catch (Exception ex) { throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex); } } } |
| After |
private class SimpleMembershipInitializer { public SimpleMembershipInitializer() { //Database.SetInitializer<UsersContext>(null); try { //using (var context = new UsersContext()) //{ // if (!context.Database.Exists()) // { // // Create the SimpleMembership database without Entity Framework migration schema // ((IObjectContextAdapter)context).ObjectContext.CreateDatabase(); // } //} WebSecurity.InitializeDatabaseConnection("ConnStringForWebSecurity", "TestUser", "Id", "UserName", autoCreateTables: true); } catch (Exception ex) { throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex); } } } |
Finally Modify your web.config file by adding
<add key="enableSimpleMembership" value="true" />
in side your <appSettings>.


