Tag Archives: Tutorial

Loading forms dynamically in WPF

A friend of mine who is learning WPF recently asked me how to load forms dynamically into the panes of a tab control. Being the helpful sort I am, I wrote up a quick app that demonstrates this.

Essentially, the idea is to create the forms as UserControls, and then load these at runtime into the host control (either a TabItem or some other Content or Item control such as a Grid). Remember that for a Content Control, you would set mycontrol.Content to the new form, while an Items control can contain multiple children, so to replace the content with a form you would call mycontrol.Children.Clear(), followed by mycontrol.Children.Add(newform).

The demo app is available here.

Advertisements

31 Days of Refactoring on LosTechies

August is Refactoring Month for Sean Chambers over on LosTechies.  Some of the methods he looks at are well known, some not so much, but all are worth knowing.  Check it out at http://www.lostechies.com/blogs/sean_chambers/archive/2009/07/31/31-days-of-refactoring.aspx.

Extending the Microsoft ASP.NET Membership Provider

Microsoft did a wonderful thing when they gave us the ASP.NET Membership Provider.  With a single command line call to aspnet_regsql.exe, we can have a fully implemented membership system providing persistence of usernames, one-way encrypted passwords, question / answer combinations, account lockout, roles, personalization, and all sorts of other useful (and not-quite-so-useful) features.

However, there is also a bit missing.  Most websites will also want to store a bit more information about their users, such as first / last names, maybe their address, birthdate, favorite color, etc, etc.  For Microsoft to have supplied fields for all of this would have made things quite unwieldy, to say the least, but fortunately there is an easy way to extend the provider.

DISCLAIMER: Before I begin, let me say that this is not the only way to extend the provider, nor is it necessarily the best.  It is quite simple, however, and therein lies it’s appeal…

Database Tables

Once you have decided which fields you wish to add to the membership provider, create a table that includes these fields along with an ID field (you can call it what you want, but ID or UserID are obvious choices) of type uniqueidentifier.

The value in the ID field will be used to link to the ASP.NET Membership Provider tables (the UserId field in aspnet_Users).  You can create a relationship between these fields if you want, but I don’t worry about it as it saves messing with the auto-generated tables.  The table structure I am using for this example is as shown below:

databasetables

MyUser class

Create a class for your membership provider, called something like MyUser.  It’s structure should be something like the following:

public class MyUser
{
    public Guid ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public string FullName
    {
        get { return FirstName + " " + LastName; }
    }

    public MembershipUser User
    {
        get { return Membership.GetUser(ID); }
    }

    public static bool IsLoggedIn
    {
        get
        {
            MembershipUser u = null;
            try
            {
                u = Membership.GetUser();
            }
            catch
            {
            }

            return (u != null);
        }
    }

    public static bool IsAdmin
    {
        // Assumes a role called "Admin"
        get { return (IsLoggedIn && Roles.IsUserInRole("Admin")); }
    }

    public bool IsUserAdmin
    {
        get { return (Roles.IsUserInRole(User.UserName, "Admin")); }
    }

    private static UsersService _service;

    private static UsersService Service
    {
        get
        {
            if (_service == null)
                _service = new UsersService();

            return _service;
        }
    }

    public static MyUser GetUser(Guid userId)
    {
        return Service.GetUser(userId);
    }

    public static MyUser GetCurrentUser()
    {
        try
        {
            return Service.GetUser((Guid)Membership.GetUser().ProviderUserKey);
        }
        catch
        {
            return null;
        }
    }

    public static MyUser AddNewUser(string username, string password, string email, string firstName, string lastName, out MembershipCreateStatus createStatus)
    {
        MembershipUser u = Membership.CreateUser(username, password, email, null, null, false, out createStatus);
        if (u != null)
        {
            MyUser user = Service.AddUser((Guid)u.ProviderUserKey, firstName, lastName);
            return user;
        }
        else
            return null;
    }

    public static MyUser ConfirmUser(Guid id)
    {
        var user = Service.GetUser(id);

        if (user != null)
        {
            if (user.User.IsApproved)
                user = null;
            else
            {
                var mu = user.User;
                mu.IsApproved = true;
                Membership.UpdateUser(mu);
            }
        }
        return user;
    }
}

Okay, there’s quite a bit there, so let’s have a look at the various parts.

Lines 3-5 provide the extended field set we want, including the Guid field (which maps to the SQL uniqueidentifier) to link to the ASP.NET Membership Provider.  Lines 7-10 just provide a quick way to get a user’s full name, while lines 12-15 provides a simple way to get to the ASP.NET Membership User.

Following this are a few static and instance methods for getting the status of a user:  Lines 17-32 is a static call to see if anyone is currently logged in;  Lines 34-38 can be used to see if the currently logged in user is a member of the Admin role (you can use several of these methods for different roles), while lines 40-43 is an instance method to see if a particular user is a member of the Admin role.

Line 45 introduces a reference to a UsersService class.  We’ll be using this service class to provide access to our database repository, and I’ll provide full details below.  This is a static field, and lines 47-56 essentially provide a single property accessor to this field (sort of a Singleton, even though it’s all static).  Following this are several methods for CRUD (Create Read Update Delete – okay, there’s no Delete here, but you get the idea..).  The only surprise here is the ConfirmUser method.  I like users to confirm their email address by clicking a link in an email sent to them, so create their user as Unapproved.  When they click on a link in an email (which contains their UserID as a parameter), the ConfirmUser method is called with that ID, which updates their status.

Now, about that UsersService…

The UsersService class

The UsersService relies on a repository class, so let’s get that first.  I’m using Linq to SQL, so create a new LINQ to SQL class, and let’s call it LinqUsers.dbml.  Drag the User table (from the top of this post) onto the designer and check your namespaces if required.  I have named my data context ‘DB’ to make things easy.  Now, here’s the UsersRepository code…

public class UsersRepository
{
    public IQueryable<MyUser> GetUsers()
    {
        DB db = new DB();
        return from u in db.Users
               orderby u.LastName
               select new MyUser
               {
                   ID = u.ID,
                   FirstName = u.FirstName,
                   LastName = u.LastName
               };
    }

    public MyUser AddUser(Guid id, string firstName, string lastName)
    {
        MyUser result = null;

        using (DB db = new DB())
        {
            User user = new User();
            user.ID = id;
            user.FirstName = firstName;
            user.LastName = lastName;

            db.Users.InsertOnSubmit(user);
            db.SubmitChanges();

            result = GetUsers().ByID(id);
        }

        return result;
    }

    public bool RemoveUser(Guid id)
    {
        bool result = false;

        using (DB db = new DB())
        {
            var del = from u in db.Users
                      where u.ID == id
                      select u;

            db.Users.DeleteAllOnSubmit(del);
            db.SubmitChanges();

            result = true;
        }

        return result;
    }
}

The only thing this needs is the ByID() filter, as follows:

public static class UserFilters
{
    public static MyUser ByID(this IEnumerable<MyUser> qry, Guid id)
    {
        return (from u in qry
                where p.ID == id
                select p).SingleOrDefault();
    }
}

Now, the UsersService class can be defined as follows:

public class UsersService
{
    UsersRepository _repository = new UsersRepository();

    public IList<MyUser> GetUsers()
    {
        return _repository.GetUsers().ToList();
    }

    public MyUser GetUser(Guid id)
    {
        return _repository.GetUsers().ByID(id);
    }

    public MyUser AddUser(Guid id, string firstName, string lastName)
    {
        return _repository.AddUser(id, firstName, lastName);
    }

    public bool RemoveUser(Guid id)
    {
        MyUser user = _repository.GetUsers().ByID(id);
        if (user == null)
            return false;

        MembershipUser mu = user.User;
        _repository.RemoveUser(id);
        return Membership.DeleteUser(mu.UserName, true);
    }
}

This should all be fairly self explanatory.  The reference to the UsersRepository could be taken through a constructor, and the UsersRepository should really implement an IUsersRepository interface, so that IOC and Dependency Injection can be used to enable unit testing, but if you need it, you’ll know how to do it (yes, I do it on my own code, so don’t beat me…).

So that’s it, really.  While there is a fair whack of code in there, it’s all fairly simple stuff.  Linq to SQL makes the database work easy, and the database and MyUser class are easily extendable to provide for the management of more fields and roles.  Feel free to leave comments if this has helped, or to offer suggestions for how this could be improved.