Nozoku
Nozoku

Reputation: 145

Routing in MVC 3

I'm not quite sure how to go about doing this. Basically I have a domain, we'll just call it domain.com. The domain itself is the corporate website, and then there are franchisee websites that are accessed through a forward slash parameter. So for example domain.com/atl might be the franchisee website. These franchisee websites are the same as the corporate website so you are essentially just recreating the whole site for each franchisee.

Here's the tricky part for me. Certain pages on the franchisee websites need to be customizable. So my idea is that this should be controlled by a database and I would just take the "atl" as a parameter that hits the database and returns content for a page based on the link clicked, that way I have essentially 1 view file that can serve unlimited number of franchisees.

What I don't understand is how you then pass around this parameter. Links for example. Lets say I go to domain.com/atl and I click on a link called "stuff". What would you do to route it in such a way that it goes to the "stuff" view and displays it as domain.com/atl/stuff instead of domain.com/stuff?

Is there a word to describe this system that will make my research easier? Or does anyone have a link that would point me in the right direction? Thanks.

Upvotes: 1

Views: 222

Answers (3)

danludwig
danludwig

Reputation: 47375

MikeSW is close about the route, but it sounds like you don't want the franchisee pages to share any controllers with corporate pages. I have a couple other thoughts too:

routes.MapRoute(null, // do not name your routes, they are "magic strings"
    "{tenant}/{controller}/{action}",
    new
    { 
        // strongly type controller, action, and area names using T4MVC
        controller = MVC.Home.Name,            
        action = MVC.Home.ActionNames.Index,
        // it sounds here like you want this controller for franchisees only, 
        // so corporate pages will use other controllers. if this is the case, 
        // tenant="default" // require the parameter by not supplying a default
    });

The reason not to name your routes is because not naming them forces you to use certain overloads in some html helper and controller methods. A lot of overloads in methods like RedirectToRoute, @Html.RouteLink, and @Url.RouteUrl take route name as the first argument. By omitting names from routes, this forces us to use the overloads that depend only on route parameters and HTTP method to resolve controller and action. (T4MVC is helpful here as well because it allows us to strongly-type the area, controller, and action names for the arguments to these methods.)

MVC will automatically use "ambient" route parameters in the URL for which the view is rendered. So, if you are at the URL domain.com/atl and want to link to domain.com/atl/stuff, you can output a hyperlink like this:

@Html.RouteLink("Stuff", new 
{
    // this will render a link with the URL domain.com/atl/stuff
    controller = MVC.Stuff.Name,
    action = MVC.Stuff.ActionNames.Index,
    // you do not need to include franchisee
})

(If you want to render just the URL for the href parameter of a normal HTML <a> tag, use @Url.RouteUrl instead.)

On the other hand, if you want to link from one franchisee site to another, you would have to specify the franchisee parameter:

@Html.RouteLink("Another franchisee in this state", new 
{
    // this will render a link with the URL domain.com/macon
    controller = MVC.Home.Name,
    action = MVC.Home.ActionNames.Index,
    franchisee = "macon"
})

Upvotes: 1

Brett Allred
Brett Allred

Reputation: 3487

There is a different approach you could take by actually creating a multi tenant web application using an IOC container like structuremap. Zack Owens has a starter sample on how do this

Creating a multi tenant web app is obviously more than can be put in a post but you could msg me if you wanted some more information.

I think if you try to handle it all with routing your are going to create a mess.

Upvotes: 0

MikeSW
MikeSW

Reputation: 16348

In a route, the view doesn't matter, only the controller matters as it selects a view to return. I think it's about multi tenancy after all and at least in this case teh anwser is quite simple. Have a route definition which includes the tenant name or id

routes.MapRoute("default","{tenant}/{controller}/{action}",new{ tenant="default", controller="home", action="index"})

With this route if the tenant is not specified is asumed to be the "default" (maybe the corporate site itself).

About some pages needing to be customizable, the database is to store things, not to control logic. I think, things are simpler than you imagine, you just need to storare some customization details in the db (a certain view name or the CSS, js) and then feeds those to the view. Basically, the controller gets the minimum informationa required from the db then selects the relevant view, create the view model and returns that view.

Upvotes: 0

Related Questions