How to initialize simple membership in ASP.NET MVC4

7.8k Views Asked by At

How to initialize simple membership in ASP.NET MVC4

Hi, I'm working on ASP.NET MVC4. As you know, membership/authentication mechanism is disabled in ASP.NET MVC4; if we want to enable it, we need to:

1) edit the follow line(in the constructor of the class SimpleMembershipInitializer, file InitializeSimpleMembershipAttribute.cs)

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "users", "id", "username", autoCreateTables: true);

2) add a new key to in your Web.Config section.

<appSettings>
    <add key="enableSimpleMembership" value="true" />
    ...
</appSettings>

Right? You can find some information here and here.

NB: I have already created table 'users' in my database, DefaultConnection is set correctly.

EDIT: let "DefaultConnectionString" be

  <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=aspnet-SimpleAuthenticationMvc4-20140209174604;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
  </connectionStrings>

When I attempt to "login" in my web-application, I get a TargetInvocationException when calling EnsureInitialized(): here the complete source code of my InitializeSimpleMembershipAttribute class:

/* class MyApp.Filters.InitializeSimpleMembershipAttribute */

namespace MyApp.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
            // HERE i _always_ get TargetInvocationException
            LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
        }

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

                    /* DefaultConnection and table 'users' should/seems to be OK */
                    WebSecurity.InitializeDatabaseConnection("DefaultConnection", "users", "id", "username", autoCreateTables: true);

                }
                catch (Exception ex)
                {
                    ...
                }
            }
        }
    }
}

Someone suggested me that this error can mean that the simple membership is initialized in another part of the application, but I do not understand where this might happen: Here is the text of my global.asax.cs:

/* file global.asax.cs */

namespace MyApp
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();
        }
    }
}

Nothing strange, as you can see. I also tried to move around within the file global.asax.cs, as is suggested here, but even so I get the same exception.

I have no special requirements: I only want to log-in in my MVC 4 application, as I do with MVC3 app I have written previously.

Can anyone suggest me where is the mistake?

Thanks!

IT

1

There are 1 best solutions below

9
On

Okay I am assuming you want to use your existing users table right? Is "DefaultConnection" your connection string? I am assuming not. So you should use your connection string instead.

Initially I also ran into an initialization issue so I preferred to ditch the filter and initialize it directly in global.asax by

if (!WebSecurity.Initialized)
            {
                WebSecurity.InitializeDatabaseConnection("YOUR_DB_CONTEXT", "USER_TABLE", "ID_COLUMN", "USERNAME_COLUMN", true);
            }

I posted my tutorial on setting it up Here. I think it can help you.