1

I have a database-first ASP.NET MVC 4 project and would like to use the SimpleMembershipProvider with the custom user_info table in my database. I am using Entitiy Framework 6 with SQL Server. I have scoured the internet and SO for a solution, but with no luck.

My user_info table looks like this:

[Id]            INT            IDENTITY (1, 1) NOT NULL,
[email]         NVARCHAR (MAX) NULL,
[first_name]    NVARCHAR (MAX) NULL,
[last_name]     NVARCHAR (MAX) NULL,
[internal_role] INT            NULL,
CONSTRAINT [PK_user_info] PRIMARY KEY CLUSTERED ([Id] ASC)

I have tried to follow the steps in How can I customize simple membership provider to work with my own database ASP.NET mvc 4, but I don't think this method will work for non-Code-First projects. I get the server error "Unable to find the requested .Net Framework Data Provider. It may not be installed." when I try to add the following code to the function SimpleMembershipInitializer().

WebSecurity.InitializeDatabaseConnection("ReservationSystemEntities", "user_info", "Id", "email", autoCreateTables: true);

Here is the relevant info from my Web.config file:

<configSections>
  <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=xxxxxx" requirePermission="false" />
</configSections>

<connectionStrings>
<add name="ReservationSystemEntities" connectionString="metadata=res://*/ReservationSystem.csdl|res://*/ReservationSystem.ssdl|res://*/ReservationSystem.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=(localdb)\v11.0;initial catalog=ReservationSystem;integrated security=True;user id=xxxxx;password=xxxxx;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
</connectionStrings>

<entityFramework>
  <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
  <providers>
    <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
  </providers>
</entityFramework>

I'm not even sure if this is possible, based on this answer: SimpleMembershipInitializer won't initialize

Based on this answer Using MVC 4 SimpleMembership with an existing database-first EF model I need to specify a connection string like this:

<add name="CONNECTION_STRING_NAME" connectionString="data source=SERVER;initial catalog=DATABASE;user id=USER;password=PASSWORD;" providerName="System.Data.SqlClient" />

I'm not sure how to convert my connection string to a connection string like this though. Isn't this type of connection string valid only when using Code-First?

Any help would be much appreciated.

Community
  • 1
  • 1
oalbrecht
  • 413
  • 4
  • 11
  • EF6 can run against Sql Server, Compact Sql Server, Sql Server Express, or MySql. Which database server type are you using? Also, please post the EntityFramework and System.Data sections from your webconfig "leave out passwords/usernames" The error you are getting first hand, is that EF6 isn't configured right in the web.config. Or you are missing nuget packages for EF6. If you are using MySql, there are many gotchas to getting it running well. – Ryan Mann Jul 16 '14 at 04:40
  • @Ryios Thank you so much for your help. I've updated the question with the information you requested. My website worked correctly using EF6 before trying to use SimpleMembership with my own database. I was able to access the database that contains the user_info table using EF6 with no problems, until I started trying to add the WebSecurity.InitializeDatabaseConnection(...) part to the InitializeSimpleMembershipAttribute. – oalbrecht Jul 17 '14 at 01:28
  • I started my project with the SimpleMembership information in its own database. In addition to this database, I have another one that has all the tables I access using EF6. Now I want to stop using the DefaultConnection to the database that contains the SimpleMembership tables and instead use SimpleMembership my other database. – oalbrecht Jul 17 '14 at 01:33

1 Answers1

1

I finally found the answer! See Using SimpleMembership with EF model-first for the original question/answer.

SimpleMembership can work with model/database first. Here is the solution:

1.InitializeSimpleMembershipAttribute.cs from MVC 4 Internet Application templete should look like this

namespace WebAndAPILayer.Filters
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public sealed class InitializeSimpleMembershipAttribute : ActionFilterAttribute
    {
        private static SimpleMembershipInitializer _initializer;
        private static object _initializerLock = new object();
        private static bool _isInitialized;

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // Ensure ASP.NET Simple Membership is initialized only once per app start
            LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
        }

        private class SimpleMembershipInitializer
        {
            public SimpleMembershipInitializer()
            {
                try
                {
                    WebSecurity.InitializeDatabaseConnection("ConnStringForWebSecurity", "UserProfile", "Id", "UserName", autoCreateTables: true);
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException("Something is wrong", ex);
                }
            }
        }
    }
}

2.Delete CodeFirst Classes from AcountModel.cs

3.Fix AccountCotroler.cs to work with your Model-first DbContext (ExternalLoginConfirmation(RegisterExternalLoginModel model, string returnUrl) method)

4.Define your "ConnStringForWebSecurity" connection string which is not same as that funky conn string for model-first db access, notice that we use provider System.Data.SqlClient not System.Data.EntityClient

 <connectionStrings>
         <add name="ModelFirstEntityFramework" connectionString="metadata=res://*/Context.csdl|res://*/Context.ssdl|res://*/Context.msl;provider=System.Data.SqlClient;provider
 connection string=&quot;data source=.\SQLEXPRESS;Initial
 Catalog=aspnet-MVC4;Integrated
 Security=SSPI;multipleactiveresultsets=True;App=EntityFramework&quot;"
 providerName="System.Data.EntityClient" />
         <add name="ConnStringForWebSecurity" connectionString="data source=.\SQLEXPRESS;Initial Catalog=aspnet-MVC4;Integrated
 Security=SSPI" providerName="System.Data.SqlClient" />
       </connectionStrings>
Community
  • 1
  • 1
oalbrecht
  • 413
  • 4
  • 11