Question

I am trying to use hijacking to do a single-page web application using mvc. The problem that I find is how to toggle the layout that the controller returns in an efficient way.

the most obvious non efficient solution would be to use this code on every controller:

if (Request.IsAjaxRequest())
{
    return PartialView();
}
else
{
    viewdata["controller"]= "x"; viewdata["action"]= "y"; 
    return View("defaultview"); //I need view data because only one template main
                                //view is returned and based on the viewdata the main 
                                //view loads the right partial view inside it
}

Is there a way to do the above code in a more simpler way? Maybe using a custom viewresult, which checks, if the request is AJAX, and returns the proper view. Or maybe some-sort of a base controller? I do not know how to implement both ideas so any guidance would be great.

Was it helpful?

Solution

One possibility is to write a custom action filter and subscribe to the OnActionExecuted event. Inside you will check if the action was invoked using an AJAX request and if it returned a view result. In this case you will substitute this view result with a partial view result:

public class LayoutSelectorAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var result = filterContext.Result as ViewResult;
        if (filterContext.HttpContext.Request.IsAjaxRequest() && result != null)
        {
            var partialViewResult = new PartialViewResult
            {
                ViewName = result.ViewName,
                ViewData = result.ViewData,
                TempData = result.TempData
            };
            filterContext.Result = partialViewResult;
        }
    }
}

Now you could decorate your controllers or actions with this attribute.

If you are using the Razor view engine another possibility is to tweak your _ViewStart.cshtml file which is where the layout is defined:

@{
    Layout = !ViewContext.HttpContext.Request.IsAjaxRequest() 
        ? "~/Views/Shared/_Layout.cshtml" 
        : null;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top