views:

109

answers:

1

I have a controller attribute called [RequiresCompletedProfile], that I can put on action methods to disallow a user from going there unless they have completed their profile.

This was working fine when I had one kind of user, but the app has since evolved into having 2 kinds of users: Vendors and Clients.

So, there is no longer a "User_Profile" table. There is now a "Client_Profile" and a "Vendor_Profile" and their schemas are different. I should note that I'm using LINQ but I'm mapping all LINQ objects to POCO before returning them out.

My solution was to make an interface called "User_Type", that had the following method:

bool IsProfileCompleted();

Now my Client objects and my Vendor objects can both implement the interface and be responsible for determining if their fields/members constitute their profile being completed.

However, now that I have multiple user types, I can't be sure which table to pull the profile from, so I have to do something like this:

public class RequiresCompleteProfileAttribute : ActionFilterAttribute
{
    IUserRepository userRepo = new SqlUserRepository();
    IClientProfileRepository clientProfileRepo = new SqlClientProfileRepo();
    IVendorProfileRepository vendorProfileRepo = new SqlVendorProfileRepo();

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.User.Identity.IsAuthenticated)
        {

            // Database call #1
            var user = userRepo.GetUserByUsername(User.Identity.Name);

            UserType profile;

            if (user.UserTypeName == "Client")
            {
            // Database call #2
            profile = clientProfileRepo.GetClientByUserName(filterContext.HttpContext.User.Identity.Name);

            }
            else
            {
            // Database call #2
            profile = vendorProfileRepo.GetClientByUserName(filterContext.HttpContext.User.Identity.Name);
             }

            if (!profile.IsProfileCompleted())
                filterContext.HttpContext.Response.Redirect("/admin/editprofile/");


        }

        base.OnActionExecuting(filterContext);
    }

}

You can see here that I have to make 2 database calls, one to determine the type of the user, and the other to get the profile from the appropriate table.

Is this bad practice? If so, what should I do instead?

+4  A: 

It's not exactly bad practice, but you'd be well served by having a middle layer business object that encapsulates the logic of querying the client by username based upon the usertypename.

McWafflestix
@McWafflestix, can you elaborate a bit? I should create a service class that does what exactly?
FalconKick