views:

50

answers:

2

Hello,

I am working on a simple MVC2 multi-tenant application. My question is how do I determine which tenant portal has been asked for in the url by the user? What I need to have happen is this:

The two routes below achieve this and seem to work fine.

routes.MapRoute(
    "Client Portal Default", // Route name
    "{clientportal}/{controller}/{action}/{id}", // URL with parameters
    new { controller = "ClientPortalHome", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults,
);

My question is how do I determine which client portal has been asked for (client1 in the above example)?

I tried using this:

private void Application_BeginRequest(Object source, EventArgs e)
{
    var route = RouteTable.Routes.GetRouteData(new HttpContextWrapper(Context));
    var currentPortal = route.GetRequiredString("clientportal");

    Context.Items.Add("ClientPortalName", currentPortal);
}

The problem is that it is called for all routes and throws an exception for the Home controller case because the route does not contain a “clientportal” entry.

What’s the best way to determine which portal has been requested so I can make sure it exists and show the client specific home page? Do I need a custom route handler?

Thank you in advance.

Rick

+1  A: 

This should work:

private void Application_BeginRequest(Object source, EventArgs e)
{
    var route = RouteTable.Routes.GetRouteData(new HttpContextWrapper(Context));

    object currentPortal;
    if(route.Values.TryGetValue("clientportal", out currentPortal))
    {
        Context.Items.Add("ClientPortalName", currentPortal);
    }
}
Dave
I forgot about TryGet! Thanks!
rboarman
A: 

What do you guys think about about a route handler? What are the pros and cons of this approach vs. Application_BeginRequest?

public class PortalRouteHandler : IRouteHandler
{
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        var portalName = requestContext.RouteData.GetRequiredString("clientportal");
        if (!string.IsNullOrWhiteSpace(portalName))
        {
            // Grab the portal details from the database
            var portalEntity =
                Repository.For<ClientPortalEntity>().GetAll().Where(x => x.PortalTag == portalName).First();
            if (portalEntity != null)
            {
                // Register db object for use by controllers
                IoC.Container.RegisterInstance<ClientPortalEntity>(portalEntity);
            }
        }

        // Return the default MVC HTTP handler for the configured request
        return new MvcHandler(requestContext);
    }
}
rboarman
You forgot about TryGetValue again... :-)
Dave
I implemented the code before I saw your post. Sorry! Which approach is better? Also, how can I show an error page of they enter a bad portal name?
rboarman
I'm not sure, which solution is better... seems to me they are quite equal. I would go with the first approach (global.asax), because I have it all in one place, otherwise, with the second approach, the concerns maybe are better separated...
Dave
For the second question: You could implement an ErrorController with the action PortalNotFound or something similar. Then check in your check, if portalEntity is not null add an else clause with a redirect to "/Error/PortalNotFound". Im not sure if it work, but you could try to directly modify the route values.
Dave