MySQL Forums
Forum List  »  MySQL for Visual Studio

Using a Class Libray for ASP.NET Membership Provider with MySQL
Posted by: Raymond Brack
Date: September 28, 2015 12:56AM

I am attempting to use the ASP.NET Membership Provider with a MySQL database with mixed success. My solution currently contains an ASP.NET MVC project that has been configured to use MySQL and another project that handles all calls to the database in which I also want to handle membership functions such as creating and validating users.

Both projects have MS .NET EnityFramework v6.1.3, Microsoft.AspNet.Identity.EntityFramework v2.2.1 and MySql.Data.Entity v6.9.7 installed.

I configured the ASP.NET project as per the instructions at http://k16c.eu/2014/10/12/asp-net-identity-2-0-mariadb/. My "web.config" is configured as follows;

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<remove name="LocalMySqlServer" />
<add name="LocalMySqlServer"
connectionString="Server=localhost; Database=rb-web; Uid=root; Pwd=password; Convert Zero Datetime=True; Allow User Variables=True;"
providerName="MySql.Data.MySqlClient" />
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.9.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</providers>
</entityFramework>
<system.data>
<DbProviderFactories>
<remove invariant="MySql.Data.MySqlClient" />
<add name="MySQL Data Provider"
invariant="MySql.Data.MySqlClient"
description=".Net Framework Data Provider for MySQL"
type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>
</system.data>
</configuration>

The instructions at http://k16c.eu/2014/10/12/asp-net-identity-2-0-mariadb/ required creating two new classes, ApplicationUser.cs and ApplicationContext.cs however these were basically replicating the code in IdentityModels.cs which was already included in my project. The identity model code is;

using System.Data.Entity;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using MySql.Data.Entity;

namespace RB.Client.Models
{
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
}
[DbConfigurationType(typeof(MySqlEFConfiguration))]
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext() : base("LocalMySqlServer", throwIfV1Schema: false) { }
public ApplicationDbContext(string connStringName) : base(connStringName, throwIfV1Schema: false) { }
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

#region Fix asp.net identity 2.0 tables under MySQL
// Explanations: primary keys can easily get too long for MySQL's
// (InnoDB's) stupid 767 bytes limit.
// With the two following lines we rewrite the generation to keep
// those columns "short" enough
modelBuilder.Entity<IdentityRole>()
.Property(c => c.Name)
.HasMaxLength(128)
.IsRequired();

// We have to declare the table name here, otherwise IdentityUser
// will be created
modelBuilder.Entity<ApplicationUser>()
.ToTable("AspNetUsers")
.Property(c => c.UserName)
.HasMaxLength(128)
.IsRequired();
#endregion
}
}
}

Once these changes were made running the Enable-Migrations, Add-Migration "Initial" and Update-Database command from the Package Manager Console created the necessary tables in MySQL (aspnetusers, aspnetroles, aspnetlogins, etc).

I then use the following code in my persistence project;

public UserDto RegisterUser(UserDto user)
{
var appUser = Membership.CreateUser(user.Email, user.Password);
}

Which raises the exception;

"Unable to initialize provider. Missing or incorrect schema."
"MySql.Web"
"at MySql.Web.Common.SchemaManager.CheckSchema(String connectionString, NameValueCollection config)
at MySql.Web.Security.MySQLMembershipProvider.Initialize(String name, NameValueCollection config)
at System.Web.Configuration.ProvidersHelper.InstantiateProvider(ProviderSettings providerSettings, Type providerType)"

However, if I add the following entries to the "web.config";

<system.web>
<roleManager defaultProvider="MySQLRoleProvider">
<providers>
<remove name="MySQLRoleProvider" />
<add name="MySQLRoleProvider"
type="MySql.Web.Security.MySQLRoleProvider, MySql.Web, Version=6.9.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"
applicationName="/RBWeb"
description="RB Role Provider"
connectionStringName="LocalMySqlServer"
writeExceptionsToEventLog="True"
autogenerateschema="True"
enableExpireCallback="False" />
</providers>
</roleManager>
<membership defaultProvider="MySQLMembershipProvider">
<providers>
<remove name="MySQLMembershipProvider" />
<add name="MySQLMembershipProvider"
type="MySql.Web.Security.MySQLMembershipProvider, MySql.Web, Version=6.9.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"
applicationName="/RbWeb"
description="RB Membership Provider"
connectionStringName="LocalMySqlServer"
writeExceptionsToEventLog="True"
autogenerateschema="True"
enableExpireCallback="False"
enablePasswordRetrieval="False"
enablePasswordReset="True"
requiresQuestionAndAnswer="False"
requiresUniqueEmail="True"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="6"
minRequiredNonalphanumericCharacters="1"
passwordAttemptWindow="10"
passwordStrengthRegularExpression="" />
</providers>
</membership>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>

And run the same code;

public UserDto RegisterUser(UserDto user)
{
var appUser = Membership.CreateUser(user.Email, user.Password);
}

The user is successfully created and a Syste.Web.Security.MembershipUser object is returned. However the call has now generated a number of new tables in the database, my_aspnet_users, my_aspnet_roles, etc along with all of the tables for profiles, personalisation, and session management even though these options werenm't included in the web.config settings.

I have reviewed all of the articles I could find in MySQL however these all appear to be out of date and were of no help. At this point I am now writing a custom membership provider to try and get around these problems but to be honest I'm also considering ditching MySQL due to the problems I have faced trying to get this to work.

If anyone can resolve this issue I would be very grateful.

Options: ReplyQuote


Subject
Views
Written By
Posted
Using a Class Libray for ASP.NET Membership Provider with MySQL
2424
September 28, 2015 12:56AM


Sorry, you can't reply to this topic. It has been closed.

Content reproduced on this site is the property of the respective copyright holders. It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.