Search code examples
c#asp.net-mvcentity-frameworkasp.net-membershiplibraries

How to link MVC application with membership provider and data model in different class libraries together?


I have 3 class libraries and ASP.MVC 4 web application.

  1. Library - Base data model (users, roles, etc...)
public class User
{
  public int ID { get; set; }
  public string Comments { get; set; }....
}
  1. Library - Extended data model (Partners, Products) - this can vary with the different web app.
  2. Library - Membership provider.

I create my DBContext in the MVC app, as only there I know which DBSet I need for current app.

public class DSContext:DbContext
{
   public DbSet<User> Users { get; set; }
}

I can access and use models from both data libraries in MVC app (and it works), but how to tell membership provider to use the same DBContext that I use in MVC app something like this?

var pUser = SomeDBContext.Users.Find(Username);
return new MembershipUser(...Set properties from pUser...);

SomeDBContext can be any DbContext that has property Users with type User from first class library.

After some trial and error got the solution to this Feel free to comment - as I do not know how correct it is.

  1. Class library
public class User
{
   [Required]
   [Key]
   public string UserName{get; set;}
   public string PassWord{ get; set;}
}

public class UserContext : DbContext
{
   public DbSet<User> Users { get; set; }
}
  1. Provider - the key was to make it abstract
public abstract class STMembershipProvider : ExtendedMembershipProvider

and to add abstract property

public abstract CL.UserContext DB { get; }

public override bool ValidateUser(string username, string password)
{

    User dbuser = DB.Users.Find(username);

    if (dbuser != null)
    {
        if (dbuser.PassWord == password) return true;
    }
    return false;
}
  1. In MVC application create local DbContext what inherits from class library DbContext and local provider that inherits from MembershipProvider in the library.
public class EFContext:CL.UserContext
{

}

and

public class LocalMp:MP.STMembershipProvider
{
    public override CL.UserContext DB
    {
        get
        {
            return new EF.Models.EFContext();
        }
    }
}

and that did the magic :)


Solution

  • To use general library for user rights and access you have to design an abstract layer which will be used by your membership provider. Since DBContext is directly connected to specific business domain and you want to use a general library for access and authorization you need to map specific objects of your project to that abstract layer. I can imagine that such abstract layer should allow to operate on entities (or tabels) in a following way:

    1. Get a specific instance of business object
    2. Map it (or cast it) to abstract layer security object A
    3. Run your membership provider to do security work on object A
    4. Use output to decide any action (allow access, restrict access)...

    Hope this will help.