Plugging in your own Membership provider

Somebody who followed an ASP.NET course with me couldn’t find the necessary plugs to add your own providers to the .NET infrastructure. Since more will probably benefit I’m sharing with you all the necessary steps.

So you have your users stored somewhere in a database and can’t use the out of the box implementations that ship with the .NET framework. What are the steps that you need to do?

First, create a class that inherits from the abstract MembershipProvider and implement all the functionality you want to support. The more you add the better all the components that rely on it will be able to function. To just get beyond an MVC3 login page or a login with an ASP.NET webcontrol you just need to implement the validate user method.

//other methods omitted for brevity
public override bool ValidateUser(string username, string password)
{
    //here you'll connect with your custom database or service
    using (var context = new MyUserContext())
    {
        var user = context.MyUsers.Where(x => x.Name.Equals(username)).SingleOrDefault();
        return user != null;
    }
}

For this demonstration I’m just checking if I have a user with the same username in my database.

With our class in place we now need to plug it into the provider model, open your web.config navigate to the system.web node and configure your provider. If you added any additional configuration properties in your custom provider you can configure them there as well.

<membership defaultProvider="MyMembershipProvider">
    <providers>
        <clear/>
        <add name="MyMembershipProvider" 
             type="MvcApplication2.MyMembershipProvider" 
             applicationName="/" />
    </providers>
</membership>

Done.

More guidance can be found on MSDN.

Entity Framework 4.1 – One To One Mapping

In the snippet below you can see that a customer has an address property.

    public class Customer
    {
        public Customer()
        {
           Address = new Address();
        }
 
        public Guid Id { get; set; }
        public string Name { get; set; }
        public Address Address { get; set; }
        public Guid AddressId { get; set; }
    }
 
    public class Address
    {
        public Guid Id { get; set; }
        public string City { get; set; }
        public string Country { get; set; }
        public string Street { get; set; }
    }

The database that gets generated though defines this as a one to many relationship.

Which is not what you’re expecting, or is it? I haven’t defined any restrictions on the address class so indeed an address could be shared between multiple customers. Let’s change that.

    public class Customer
    {
        public Customer()
        {
           Address = new Address();
        }
 
        public Guid Id { get; set; }
        public string Name { get; set; }
        public Address Address { get; set; }
 
    }
 
    public class Address
    {
        public Guid Id { get; set; }
        public string City { get; set; }
        public string Country { get; set; }
        public string Street { get; set; }
        [Required]
        public Customer Customer { get; set; }
    }

I’ve added a navigation property from Address to Customer and marked the Customer property as required. This basically is telling EF that there is a one to one mapping between the two and the primary key of the customer should be used in the relationship. The primary key of the customer will also become the primary key of the address. If you did not add the required attribute you’ll get an invalidoperationexception saying that it’s unable to determine the principal end of an association.

You can also use the fluent api.

    public  class  CustomerContext
        : DbContext
    {
        public IDbSet<Customer> Customers { get; set; }
 
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Address>().HasRequired(x => x.Customer);
            base.OnModelCreating(modelBuilder);
        }
 
    }

They both result in the same database structure.

What if both ends are required? A customer always has an address and an address always has a customer. Marking both ends as required will again result in the same exception as before.

In order to model this you have to use the fluent api and there are two ways to achieve the desired result.

    public  class  CustomerContext
        : DbContext
    {
        public IDbSet<Customer> Customers { get; set; }
 
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Address>()
                .HasRequired(x => x.Customer)
                .WithRequiredDependent(x => x.Address);
            base.OnModelCreating(modelBuilder);
        }
    }

I’m saying here that the address entity has a required customer property and that the customer class is actually in charge, MSDN reference.

Resulting database structure:

Another way to achieve the same result:

    public  class  CustomerContext
        : DbContext
    {
        public IDbSet<Customer> Customers { get; set; }
 
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Address>()
                .HasRequired(x => x.Customer)
                .WithRequiredDependent();
            modelBuilder.Entity<Customer>()
                .HasRequired(x => x.Address)
                .WithRequiredPrincipal();
            base.OnModelCreating(modelBuilder);
        }
    }

MSDN link on WithRequiredPrincipal.

You saw that the WithRequiredPrincipal and Depedant actually have one taking a lambda and one with no arguments. This allows you to exclude a navigation property and still get a proper one to one mapping. Which brings me back to my starting point.

public class Customer
    {
        public Customer()
        {
           Address = new Address();
        }
 
        public Guid Id { get; set; }
        public string Name { get; set; }
        public Address Address { get; set; }
    }
 
    public class Address
    {
        public Guid Id { get; set; }
        public string City { get; set; }
        public string Country { get; set; }
        public string Street { get; set; }
 
 
    }
 
    public  class  CustomerContext
        : DbContext
    {
        public IDbSet<Customer> Customers { get; set; }
 
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Customer>()
                .HasRequired(x => x.Address)
                .WithRequiredPrincipal();
            base.OnModelCreating(modelBuilder);
        }
    }

Entity Framework 4.1 – Component mapping

By default if you add ‘simple’ property types to your class (strings, ints,…), they are all translated into columns in the database. What if you had a group of properties that actually can have some functionality together. You also have this group of properties coming back at several places in your code base. You could introduce a base class in order to improve duplication but if the two entities are not really related you should stay away from overusing the inheritance approach. What you need here is a complextype. It was present in previous releases of the Entity Framework and can be used in 4.1.

We’ll modify the customer class posted below into something a bit more object oriented.

    public class Customer
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public string City { get; set; }
        public string Country { get; set; }
        public string Street { get; set; }
    }

Customer could also have a bunch of methods that acted upon the address fields, Employee could have the same properties, the same logic and an invoice probably also has an address. So let’s move the properties, and logic, into a new class called Address. I don’t want a separate table that contains all the addresses though, I want all of the address fields to be present in the customer, employee and invoice table.

In order to achieve that result you need the ComplexType attribute.

    public class Customer
    {
        public Customer()
        {
            Address = new Address();
        }
 
        public Guid Id { get; set; }
        public string Name { get; set; }
        public Address Address { get; set; }
    }
 
    [ComplexType]
    public class Address
    {
        public string City { get; set; }
        public string Country { get; set; }
        public string Street { get; set; }
    }

Using the ComplexType attribute will result in a database table with the correct structure.

You can also use the fluent API to configure a complextype.

    public  class  CustomerContext
        : DbContext
    {
        public IDbSet<Customer> Customers { get; set; }
 
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.ComplexType<Address>();
            base.OnModelCreating(modelBuilder);
        }
 
    }