We have an existing ASP.NET MVC project which has grown to the point where making the switch to use the Bootstrap framework required a substantial amount of work to the Views. Unfortunately this isn't high priority so we couldn't afford to do this in one go, instead we had to find a solution which would enable us to deploy the solution into production using the old Views and Layouts to introduce new functionality to the solution mid-way through the Bootstrap conversion.
To overcome this problem and allow us to upgrade to Bootstrap as a side project we needed a clever solution to effectively allow us to switch from Bootstrap to the old Views and Layout quickly and easily, and then back again.
This was our solution to the problem:
- We created a Bootstrap MVC _Layout and added it to the solution.
- We created an ActionFilterAttribute class called UseBootstrapLayout which we used to decorate the Actions to denote which Layout the Action method should use to render the View.
- We copied each View we were going to upgrade to Bootstrap and named it the same but appended a 2 at the end of the filename.
- In _ViewStart.chtml we added to code (below) to check if the View ended with a 2 and which allowed us to switch to the Bootstrap Layout if it did.
If we needed to deploy the application before the Bootstrap update was complete we simply changed to _ViewStart.chtml code to use the old _Layout. All the rest of the code changes and new Views could stay the same.
/// <summary>
/// Method to change a view name used by an action method.
/// We are using this to enable us to re-skin the system
/// </summary>
public class UseBootstrapLayout : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
filterContext.RouteData.Values["action"] = filterContext.RouteData.Values["action"] + "2";
}
}
@{
// _ViewStart.chtml
var view = HttpContext.Current.Request.RequestContext.RouteData.Values["action"].ToString();
string layout = "";
if (view.EndsWith("2"))
{
layout = "~/Views/Shared/NewBootstrapLayout.cshtml";
}
else
{
layout = "~/Views/Shared/_Layout.cshtml";
}
Layout = layout;
}
[UseBootstrapLayout]
[HttpGet]
public ActionResult Index()
{
return this.View();
}