Using WebMatrix, WCF and “You must call the WebSecurity.InitializeDatabaseConnection method before you call any other method of the WebSecurity class.” error

As an addendum to my previous post regarding using WebMatrix in WCF you may run into a situation where you receive the error “You must call the WebSecurity.InitializeDatabaseConnection method before you call any other method of the WebSecurity class.” 

Should such a situation arise you might quickly discover that simply placing the initialization code into the Application_Start event handler as you normally would does not work. This is because Application_Start is part of the http pipeline and will only get invoked if a http request is made.

So whats the solution? A little known feature of the App_Code folder which basically allows you to create a global Application Start hook regardless of protocol exactly like you assume the Application_Start handler is doing. This is done by implementing any class that contains a static void AppInitialize().

In other words you can then do this.

public class App
{
    private static SimpleMembershipInitializer _initializer;
    private static object _initializerLock = new object();
    private static bool _isInitialized;

    //This is the key, any class that implements this method that lives in the App_Code folder will work
    public static void AppInitialize()
    {
        LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
    }

    public class SimpleMembershipInitializer
    {
        public SimpleMembershipInitializer()
        {
            if (!WebSecurity.Initialized)
                WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
        }
    }

}

And that’s it, you should be all good…

Advertisements

Using WebMatrix, SimpleMembershipProvider in WCF service and the “This method cannot be called during the application’s pre-start initialization stage” error.

Having made the transition to using MVC architecture for all my new applications I recently came across a situation where I needed to use the WebMatrix membership provider within my WCF services. It wasn’t a trivial process so I thought I would document it here.

So how do you get access to the SimpleMembershipProvider in WCF?

First add the references to the WebMatrix dlls

references

Second add the Web.Config reference in system.web as such

<membership defaultProvider="SimpleMembershipProvider">
  <providers>
    <add
      name="SimpleMembershipProvider"
      type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData"
      connectionStringName="MyApplicationConnectionString"
      applicationName="MyApplicationName"
      enablePasswordRetrieval="false"
      enablePasswordReset="true"
      requiresQuestionAndAnswer="false"
      requiresUniqueEmail="true"
      passwordFormat="Hashed" />
  </providers>
</membership>

Making sure you select your defaultProvider as SimpleMembershipProvider.

Lastly make sure the required assemblies are referenced in the web.config system.web.compilation.assemblies section as such.

<compilation debug="true" targetFramework="4.5">
  <assemblies>
    <add assembly="WebMatrix.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <add assembly="WebMatrix.WebData, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
  </assemblies>
</compilation>

and at that point you should be able to do this.

SimpleMembershipProvider provider = (SimpleMembershipProvider)System.Web.Security.Membership.Provider;

and use the provider now as you as you normally would i.e. ValidateUser(), ChangePassword() etc…

However at this point I ran into an issue where the following error appeared. “Parser Error Message: This method cannot be called during the application’s pre-start initialization stage.”. The solution to this problem was the following StackOverflow post and adding the these into my appSettings.

<appSettings>
  <add key="autoFormsAuthentication" value="true"/>
</appSettings>

Which successfully fixed the problem and everything worked at that point.