Can SimpleMembership be used with EF model-first? When I try it, I get "Unable to find the requested .NET Framework Data Provider" when I call WebSecurity.InitializeDatabaseConnection.
To put it another way: I can't get the call to WebSecurity.InitializeDatabaseConnection
to work when the connection string employs the System.Data.EntityClient
provider (as it does when using the model-first paradigm).
To repro the issue, create an MVC 4 app, and replace the code-first UserProfile entity class (which you get for free with the MVC 4 template) with a model-first User class that you have created in the Entity Designer:
User
to the model, with fields for Id,
UserName, and FullName
. So, at this point, the User
data entity is mapped to a Users
table and is accessed via a funky connection string that employs the System.Data.EntityClient
provider.User
entity. One easy way to do that is to scaffold out a Users controller based on the User table and its associated DbContext.AccountModels.cs
file to remove the UserProfile
class and its associated UsersContext
class. Replace the references to the (now missing) UserProfile
and UsersContext
classes with references to your new User class and its associated DbContext
class.InitializeSimpleMembershipAttribute
class and the references to it.When you run the repro, it will get an Exception at the call to InitializeDatabaseConnection.
Bob
SimpleMembership can work with model 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="data source=.\SQLEXPRESS;Initial Catalog=aspnet-MVC4;Integrated Security=SSPI;multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" /> <add name="ConnStringForWebSecurity" connectionString="data source=.\SQLEXPRESS;Initial Catalog=aspnet-MVC4;Integrated Security=SSPI" providerName="System.Data.SqlClient" /> </connectionStrings>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With