3

I am developing a website in MVC 2.0. I want to change the View folder location in my website. I wanted to keep the views folder inside other folders, When I try to do so i am getting following errors

The view 'Index' or its master was not found. The following locations were searched:
~/Views/Search/Index.aspx
~/Views/Search/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

My Views folder will be in ~/XYZ/ABC/Views instead of ~/Views. Please solve my problem. Will I get any problems If I change the default Views folder location. Do I need to change anything in HTML Helper classes because I don't know anything in MVC as this is my starting project i dont want to risk..Please help me out...

DaveRandom
  • 87,921
  • 11
  • 154
  • 174
Vinay Kumar Chella
  • 1,719
  • 6
  • 23
  • 35

3 Answers3

5

You'll need to create a custom view engine and use that instead. Fortunately you can just inherit from the default one and change the locations on the constructor. Here's a guide to creating your own view engine: http://www.singingeels.com/Articles/Creating_a_Custom_View_Engine_in_ASPNET_MVC.aspx

From the article:

protected void Application_Start()
{
    //... other things up here.

    // I want to REMOVE the ASP.NET ViewEngine...
    ViewEngines.Engines.Clear();

    // and then add my own :)
    ViewEngines.Engines.Add(new HoTMeaTViewEngine());
}

public class HoTMeaTViewEngine : VirtualPathProviderViewEngine
{
    public HoTMeaTViewEngine()
    {
        // This is where we tell MVC where to look for our files. This says
        // to look for a file at "Views/Controller/Action.html"
        base.ViewLocationFormats = new string[] { "~/Views/{1}/{0}.html" };

        base.PartialViewLocationFormats = base.ViewLocationFormats;
    }
}
Cain
  • 918
  • 6
  • 9
  • If you don't want to go the whole hog and create your own ViewEngine you can just set the location formats on an existing engine in App_Start: ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new WebFormViewEngine { LocationFormats = new string[] { "~/Views/{1}/{0}.html" } ... }); – Cargowire Dec 20 '10 at 18:38
3

Check this place out. How to change default view location scheme in ASP.NET MVC?

                           base.ViewLocationFormats = new string[] { 
                "~/Views/{1}/{2}/{0}.aspx", 
                "~/Views/{1}/{2}/{0}.ascx", 
                "~/Views/Shared/{2}/{0}.aspx", 
                "~/Views/Shared/{2}/{0}.ascx" ,
                 "~/Views/{1}/{0}.aspx", 
                "~/Views/{1}/{0}.ascx", 
                "~/Views/Shared/{0}.aspx", 
                "~/Views/Shared/{0}.ascx" 

Even easier is this one Can I specify a custom location to “search for views” in ASP.NET MVC?

Community
  • 1
  • 1
griegs
  • 22,624
  • 33
  • 128
  • 205
0

As an alternative, you can override the view engine locations for a specific controller without affecting the view engines for the other controllers.

These are some snippets from a product I am developing, but it shows the constructor for one of my controllers, and a view engine I made specificially for controllers that inherit from KBRenderMvcController.

So any controller based off KBRenderMvcController will also have my view engine.

However at no point did I clear the view engine collection, which is relevant. Because I wanted the views my product is using to fall back to default locations.

In short, if you delete \App_plugins\Product\Views\MyView And instead create a \Views\MyView it will still render from \Views\MyView instead.

Also in the ViewEngine I demonstrate code that determines the type of controller being used and if it's not a target controller I return empty view locations so they don't get used for other controllers.

    #region Constructor
    public KBRenderMvcController()
        : base()
    {
        viewEngine = new KBFrontEndViewEngine();
        if (!this.ViewEngineCollection.Contains(viewEngine))
            this.ViewEngineCollection.Insert(0, viewEngine);
    }
    #endregion

public class KBFrontEndViewEngine : RazorViewEngine
{
    #region Fields
    private static bool _Initialized = false;
    private static string[] viewLocationFormats = null;
    private static string[] partialViewLocationFormats = null;
    private static string[] viewEngineFileExtensions = new string[] { "cshtml" };
    #endregion

    #region Constructor
    public KBFrontEndViewEngine()
    {            
        if (!_Initialized)
        {
            viewLocationFormats = new string[] 
                    { 
                        string.Concat(KBApplicationCore.PluginRelUrl, "/Views/{1}/{0}.cshtml"), 
                        string.Concat(KBApplicationCore.PluginRelUrl, "/Views/Partials/{0}.cshtml") 
                    };
            partialViewLocationFormats = new string[] 
                    { 
                        string.Concat(KBApplicationCore.PluginRelUrl, "/Views/{1}/Partials/_partial{0}.cshtml"), 
                        string.Concat(KBApplicationCore.PluginRelUrl, "/Views/Partials/_partial{0}.cshtml"),
                        string.Concat(KBApplicationCore.PluginRelUrl, "/Views/{1}/Dialogs/_dialog{1}.cshtml"),
                        string.Concat(KBApplicationCore.PluginRelUrl, "/Views/Dialogs/_dialog{1}.cshtml"),
                    };
            _Initialized = true;
        }
        base.ViewLocationFormats = viewLocationFormats;
        base.PartialViewLocationFormats = partialViewLocationFormats;
        base.MasterLocationFormats = viewLocationFormats;
        base.FileExtensions = viewEngineFileExtensions;
    }
    #endregion

    #region Methods
    //Don't run on requests that are not for our hijacked controllers
    public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
    {
        Type controllerType = controllerContext.Controller.GetType();
        Type baseType = controllerType.BaseType;
        if ((baseType != null) && (baseType.Name == "KBRenderMvcController`1") || (baseType.Name == "KBFrontEndBaseSurfaceController"))
            return base.FindPartialView(controllerContext, partialViewName, useCache);
        else
            return new ViewEngineResult(new List<string>());
    }
    #endregion
}
Ryan Mann
  • 5,178
  • 32
  • 42