Winforms app fails to load SQLiteMembershipProvider

Discussion of open issues, suggestions and bugs regarding ADO.NET provider for SQLite
Post Reply
tohagan
Posts: 5
Joined: Thu 21 Feb 2013 12:00

Winforms app fails to load SQLiteMembershipProvider

Post by tohagan » Thu 21 Feb 2013 12:28

I'm writing a small C# WinForms data import app to load up data into a SQLite database to be later using in an ASP.NET app. Part of this includes importing Users using the SQLiteMembershipProvider class. Unfortunately it's failing to load the type for some reason with the 1st call to Membership.CreateUser() throwing TypeLoadException. I've included details of the exception stack and relevant App.config .

The C# project references:
Devart.Data,
Devart.Data.SQLite
Devart.DataSQLite.Web (containing the SQLiteMembershipProvider type)
System.Web

I'd rather avoid using GAC.

Any clues or suggestions appreciated.

Tony.

Exception

Code: Select all

System.TypeLoadException was unhandled by user code
  HResult=-2146233054
  Message=Could not load type 'Devart.Data.SQLite.Web.Providers.SQLiteMembershipProvider' from assembly 'System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
  Source=mscorlib
  TypeName=Devart.Data.SQLite.Web.Providers.SQLiteMembershipProvider
  StackTrace:
       at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type)
       at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName)
       at System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark)
       at System.Type.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase)
       at System.Web.Security.Membership.InitializeSettings(Boolean initializeGeneralSettings, RuntimeConfig appConfig, MembershipSection settings)
       at System.Web.Security.Membership.Initialize()
       at System.Web.Security.Membership.get_Provider()
       at System.Web.Security.Membership.CreateUser(String username, String password, String email, String passwordQuestion, String passwordAnswer, Boolean isApproved, Object providerUserKey, MembershipCreateStatus& status)
       at System.Web.Security.Membership.CreateUser(String username, String password, String email, String passwordQuestion, String passwordAnswer, Boolean isApproved, MembershipCreateStatus& status)
       at System.Web.Security.Membership.CreateUser(String username, String password, String email)
       at System.Web.Security.Membership.CreateUser(String username, String password)
       at Bizo.WL.ImportExport.Importer.ImportUsers(SQLiteConnection cnn, Int32 percent) in d:\Projects\Import\Importer.cs:line 163
       at Bizo.WL.ImportExport.Importer.Import(DirectoryInfo sqlScriptsDir, FileInfo importDbPath) in d:\Projects\Import\Importer.cs:line 114
       at Bizo.WL.ImportExport.frmImportExport.backgroundWorker1_DoWork(Object sender, DoWorkEventArgs e) in d:\Projects\Import\frmImportExport.cs:line 285
       at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
       at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)
  InnerException: 
App.config

Code: Select all

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>

  <connectionStrings>
    <!-- SQLite database used by Bizo Wireless. -->
    <add name="Stuff.DB" connectionString="DataSource=D:\db\Stuff.db" />
  </connectionStrings>

  <!-- Configure membership provider to create ASP.NET compatible users in SQLite database -->
  
  <system.web>
    <membership defaultProvider="AspNetSQLiteMembershipProvider" userIsOnlineTimeWindow="15">
      <providers>
        
        <!-- Clear preinstalled providers setup in machine.config -->
        <clear/>
        
        <!-- http://www.devart.com/dotconnect/sqlite/articles/aspproviders.html -->

        <remove name="AspNetSQLiteMembershipProvider"/>
        
        <add
          name="AspNetSQLiteMembershipProvider"
          type="Devart.Data.SQLite.Web.Providers.SQLiteMembershipProvider"
          connectionStringName="Stuff.DB"
          enablePasswordRetrieval="false"
          enablePasswordReset="false"
          requiresQuestionAndAnswer="false"
          requiresUniqueEmail="false"
          passwordFormat="Hashed"
          maxInvalidPasswordAttempts="5"
          passwordAttemptWindow="10" />
      </providers>
    </membership>
  </system.web>
</configuration>

tohagan
Posts: 5
Joined: Thu 21 Feb 2013 12:00

Re: Winforms app fails to load SQLiteMembershipProvider

Post by tohagan » Thu 21 Feb 2013 13:23

OK I've this ... There was a bug the DevArt documentation for these providers.

You need to qualify the provider type ....

<add
name="AspNetSQLiteMembershipProvider"
type="Devart.Data.SQLite.Web.Providers.SQLiteMembershipProvider, Devart.Data.SQLite.Web"
...
/>

Pinturiccio
Devart Team
Posts: 2420
Joined: Wed 02 Nov 2011 09:44

Re: Winforms app fails to load SQLiteMembershipProvider

Post by Pinturiccio » Fri 22 Feb 2013 15:00

Thank you for the information. We will make the corresponding changes to our documentation.

tohagan
Posts: 5
Joined: Thu 21 Feb 2013 12:00

Re: Winforms app fails to load SQLiteMembershipProvider

Post by tohagan » Sat 23 Feb 2013 14:35

I found another a more serious issue with this provider that made it unusable in it's current implementation.

I noticed the DevArt providers are all implemented using a common code base based on OleDB . When a new user is created, it uses GUID data type as User's primary key. The GUID is a data type supported by most databases but not SQLite so what happens is is stored the GUID in a *binary* format. This means that the primary key for these rows is displayed in tools like SQL Maestro using random characters ... making this table unmaintainable by a DBA or developer. I guess you might find some formula to decode them but I doubt that my customers would be happy with this solution. I think the SQLite implementation needs to override this case and store them as a hexidecimal string or use some other type. I'm guessing that GUIDs are probably used to avoid concurrency issues or database round trips when generating new unique keys.

tohagan
Posts: 5
Joined: Thu 21 Feb 2013 12:00

Re: Winforms app fails to load SQLiteMembershipProvider

Post by tohagan » Mon 25 Feb 2013 05:25

I just noticed that there is a connection option to use non-binary GUIDS.
I've not tested it but, it looks like this will provide the solution.
If true - GUID columns are stored in binary form;
otherwise GUID columns are stored as text.

Pinturiccio
Devart Team
Posts: 2420
Joined: Wed 02 Nov 2011 09:44

Re: Winforms app fails to load SQLiteMembershipProvider

Post by Pinturiccio » Tue 26 Feb 2013 14:14

tohagan wrote:I noticed the DevArt providers are all implemented using a common code base based on OleDB
SQLiteMembershipProvider has nothing to do with OleDB. SQLiteMembershipProvider uses our dotConnect for SQLite inside itself, which is a separate ADO.NET provider.
tohagan wrote:I just noticed that there is a connection option to use non-binary GUIDS.
I've not tested it but, it looks like this will provide the solution.
Add the following parameter to your connection string: 'binary guid = false'. This must solve the issue.

Post Reply