Skip to content

Instantly share code, notes, and snippets.

@MattHoneycutt
Created May 2, 2013 02:09
Show Gist options
  • Save MattHoneycutt/5499729 to your computer and use it in GitHub Desktop.
Save MattHoneycutt/5499729 to your computer and use it in GitHub Desktop.
A Razor view engine that supports several methods of organizing views and controllers within the same folder.
public class ModularConventionViewEngine : RazorViewEngine
{
//This needs to be initialized to the root namespace of your MVC project.
//Usually, the namespace of your Global.asax's codebehind will do the trick.
private static readonly string RootNamespace = typeof(MvcApplication).Namespace;
private static IEnumerable<string> GetPath(ControllerContext controllerContext, string viewName)
{
var paths = new List<string>();
//TODO: Cache?
var controllerType = controllerContext.Controller.GetType();
var controllerName = controllerType.Name.Replace("Controller", string.Empty);
var featureFolder = "~" + controllerType.Namespace.Replace(RootNamespace, string.Empty).Replace(".", "/");
//View in the same folder as controller (controller-folder/view.cshtml)
paths.Add(string.Format("{0}/{1}.cshtml", featureFolder, viewName));
//View in a view-folder within controller-folder (controller-folder/views/view.cshtml)
paths.Add(string.Format("{0}/Views/{1}.cshtml", featureFolder, viewName));
//View in folder with controller name within a view-folder within a controller-folder (controller-folder/views/controller-name/view.cshtml)
paths.Add(string.Format("{0}/Views/{1}/{2}.cshtml", featureFolder, controllerName, viewName));
return paths;
}
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
var paths = GetPath(controllerContext, viewName);
var path = paths.FirstOrDefault(p => VirtualPathProvider.FileExists(p));
if (path != null)
{
return new ViewEngineResult(CreateView(controllerContext, path, null), this);
}
//Check the usual suspects
return base.FindView(controllerContext, viewName, masterName, useCache);
}
public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
{
var paths = GetPath(controllerContext, partialViewName);
var path = paths.FirstOrDefault(p => VirtualPathProvider.FileExists(p));
if (path != null)
{
return new ViewEngineResult(CreateView(controllerContext, path, null), this);
}
//check the usual suspects
return base.FindPartialView(controllerContext, partialViewName, useCache);
}
}
@namtih58
Copy link

Fix to render a partial as a partial not as a view

public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
{
    var path = GetPath(controllerContext, partialViewName);

    if (path != null)
    {
        return new ViewEngineResult(CreatePartialView(controllerContext, path), this);
    }
    //check the usual suspects
    return base.FindPartialView(controllerContext, partialViewName, useCache);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment