views:

81

answers:

2

I'm trying to get the master page changed for all my aspx pages. For some reason I'm unable to detect when this function is called for a ascx page instead. Any help in correting this would be appreciated.

protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
    var action = filterContext.Result as ViewResult;
    if (action != null && action.MasterName != "" && Request.IsAjaxRequest())
    {
        action.MasterName = "Ajax";
    }
    base.OnActionExecuted(filterContext);
}
A: 

So you're saying that MasterPage is empty when you're executing actions to .ascx "pages"?

.ascx's aren't pages, they're UserControls / PartialViews. And as such they don't have master pages. They can be dropped in a mage, or a master page.. But if your request is returning an .ascx, it won't have a master page.. )

UPD: This is most likely because of the way MVC works - all the 3 parts (M-V-C) are completely independant. Which means that when your code executes inside the controller, we know nothing at all about the view. And the View is the one that selects the master page, not the controller.

Tbh if you're trying to change the way the app looks (change the master page) inside the controller - you're most likely doing something wrong. It was designed with separation of context in the first place, and you're trying to go around it :)

UPD2: So you're saying that you want to return the full page + master page for regular requests, and just the page without the master (well, clean at least) for ajax requests? You're still trying the wrong approach.

Here's what I've been doing instead:

if (!Request.IsAjaxRequest())
    return View(model);
else
    return PartialView("PartialName", model);

Exactly the same situation. If I'm loading the url in a browser - it returns the full page, master and all.. If I'm loading it later on, using an ajax call - just load the partial view. Simple and easy. And still adheres to the MVC methodology :)

Also, if you're absolutely keen on preselecting the master name.. just do it like this:

return View("ViewName", "MasterName", model);
Artiom Chilaru
No, I'm saying that MasterPAge is empty even when I'm executing an .aspx page.
devzero
Added an update
Artiom Chilaru
What I want is one central place to change the master page depending if it's Ajax request or a normal request. I don't really care where I do it, but the only central place I've come across so far is in the base controller. BTW this worked fine in VS2010 RC but does not work in RTM version of MVC2/VS2010.
devzero
After thinking a bit more about it, I actually disagree in that changing the master page belongs anywhere but in the controller. The view should only concern it self with how it looks (ie the contents of the view) then the controller should "controll" what the context (ie masterpage) the view is rendered in.
devzero
Umm.. unless I'm misunderstanding you, Ajax requests should return Json results... and will NOT have a master page in the first place, no?
Artiom Chilaru
The master page doesn't have any functionality in it.. The master page is just a visual representation of the data.. Exactly in the same way that the View is.. Or are you talking about some "other" master pages? =/
Artiom Chilaru
Ajax requests does not need to return Json, and in my case they simply return the HTML within the main <asp:ContentPlaceHolder>. The masterPage decided what context you render your view within. In this case either I render the view within a masterPage with <html><head><body> tags and quite a few other .ascx userControlls, or if it's an ajax request I render it without any context (ie just the HTML from the view). This is ideal because I then don't have to create different code for those browsers using noscript.
devzero
Check the last update :)
Artiom Chilaru
+1  A: 

If you're still keen on changing the master page based on the fact whether your request is ajax or not - I just accidentally stumbled on exactly the thing you were looking for:

http://devlicio.us/blogs/sergio_pereira/archive/2008/12/05/reusing-views-in-asp-net-mvc-for-ajax-updates.aspx

Basically, instead of overriging the OnActionExecuting method in the BaseController - override the View method! You get exactly the thing you want, with a method that seems specifically designed for it :)

protected override ViewResult View(string viewName, string masterName, object model)
{
    return base.View(viewName, Request.IsAjaxRequest() ? "Empty" : masterName, model);
}
Artiom Chilaru
Exactly what I needed. Thank you very much :)
devzero
You're very much welcome! :)
Artiom Chilaru