views:

996

answers:

6

I have a problem whereby I want to display a view differently (a different master page), depending on where it came from, but don't know where to start...

I have several routes which catch various different types of urls that contain different structures.

In the code snippet below, I have a product route, and then I have a partner site route which could also go to a product page, but let's say that this partner is Pepsi, and they want their branding on the master page, rather than our own default styling. Lets say I go to products/cola.htm. This should go to the same url as partners/pepsi/products/cola.htm, and the PartnerRedirect would be able to handle the url based on the wildcard, by translating the url wildcard (in this case, "products/cola.htm") into a controller action, and forward the user on, (but simply change the master page in the view).

routes.MapRoute(
 "Product",
 "products/{product}.htm",
 new { controller = "Product", action = "ShowProduct" }
);

routes.MapRoute(
 "ProductReview",
 "products/{product}/reviews.htm",
 new { controller = "Product", action = "ShowProductReview" }
);

routes.MapRoute(
 "Partner",
 "partners/{partner}/{*wildcard}",
 new { controller = "Partners", action = "PartnerRedirect" }
);

Is this possible? And if so, how?

Many thanks in advance.

+1  A: 

In your partners controller why don't you set a cookie that indicates which partner you want to show, and then redirects to the wildcard section of the route. That way you can show the same partner layout for all subsequent page views.

I don't know if this is what you're looking for, but it might be an option.

jonnii
A: 

It may be the devils work but you could put some code in the Partner View's codebehind to look at the URL and then set the master page programmatically in there?

jmcd
A: 

I'm not sure how you can programatically alter the master page, as I've never done that, but I'm sure it's possible (it's probably just a property on Page).

That might be worth asking as another question.

jonnii
+1  A: 

I had same issue

public class FriViewPage : ViewPage
{
    public override string MasterPageFile
    {
        get
        {
            return "~/Views/Shared/Site.Master"; // base.MasterPageFile;
        }
        set
        {
            if (ViewData["agent"].ToString() == "steve")
                base.MasterPageFile = "~/Views/Shared/Site.Master";
            else
                base.MasterPageFile = "~/Views/Shared/Site2.Master";
        }
    }
}

Then just ensure all the views inherit from FriViewPage instead of ViewPage

A: 

Acutally the MasterPageFile getter never appears to be called

A: 

You can change the MasterPage by modifying the ViewResult prior to rendering. For example, a controller action could do:

public ActionResult TestMP(int? id)
{
    ViewData["Title"] = "MasterPage Test Page";
    ViewData["Message"] = "Welcome to ASP.NET MVC!";
    ViewResult result = View("Index");
    if (id.HasValue)
    {
        result.MasterName = "Site2";
    }
    return result;
}

You could accomplish the same thing with an action filter for a more generic solution.

Matthew