Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does an MVC view need to exist in the View directory to work?

I have been writing a cms with MVC being used as the main engine for generating the pages.

I am going well, but wanted the ability to create a unique razor template per site and possibly per view if I need to.

My rules are that each project has to have a unique code which is linked with a url.

Assets for each project site are stored in a way that the location relates to the project.

So an assets associated with project C0001 would be stored in assets\C0001\ and for C0002: assets\C0002\ and so on.

What I wanted to do, to keep things tidy, was to have the razor templates associated with a project located in the assets\[ProjectCode] location too, but the problem is I am getting an error about ViewBag not existing in context.

So this won't work:

Layout = string.Concat("~/assets/",ViewBag.ProjectNumber,"/_Layout.cshtml");

Where as the following will render a page:

Layout = string.Concat("~/Views/Shared/_",ViewBag.ProjectNumber,"Layout.cshtml");

I am guessing the first layout doesnt render, because it is outside of the known search areas for views? But as I am telling it where the file is, I dont see what the problem is?

I am happy to work using the code in example 2, but could mean after a fair number of project sites the Shared views diretory will become very busy.

Just wondering if there is a reason why Views need to exist in the Views Directory?

like image 697
Luke Duddridge Avatar asked Dec 21 '22 18:12

Luke Duddridge


2 Answers

You need to copy the web.config that is located in your Views directory and put the copy in your Assets directory. Since you need to supply a full path for layouts this is not a search path issue, it needs the info in the web.config to initialise the view properly.

like image 145
Clicktricity Avatar answered May 16 '23 09:05

Clicktricity


By default, the RazorViewEngine is configured to look in the Views directory.

You can change this by creating your own RazorViewEngine instance with different paths and adding it to ViewEngines.Engines.

Its default paths are

AreaViewLocationFormats = new[] {
    "~/Areas/{2}/Views/{1}/{0}.cshtml",
    "~/Areas/{2}/Views/{1}/{0}.vbhtml",
    "~/Areas/{2}/Views/Shared/{0}.cshtml",
    "~/Areas/{2}/Views/Shared/{0}.vbhtml"
};
AreaMasterLocationFormats = new[] {
    "~/Areas/{2}/Views/{1}/{0}.cshtml",
    "~/Areas/{2}/Views/{1}/{0}.vbhtml",
    "~/Areas/{2}/Views/Shared/{0}.cshtml",
    "~/Areas/{2}/Views/Shared/{0}.vbhtml"
};
AreaPartialViewLocationFormats = new[] {
    "~/Areas/{2}/Views/{1}/{0}.cshtml",
    "~/Areas/{2}/Views/{1}/{0}.vbhtml",
    "~/Areas/{2}/Views/Shared/{0}.cshtml",
    "~/Areas/{2}/Views/Shared/{0}.vbhtml"
};

ViewLocationFormats = new[] {
    "~/Views/{1}/{0}.cshtml",
    "~/Views/{1}/{0}.vbhtml",
    "~/Views/Shared/{0}.cshtml",
    "~/Views/Shared/{0}.vbhtml"
};
MasterLocationFormats = new[] {
    "~/Views/{1}/{0}.cshtml",
    "~/Views/{1}/{0}.vbhtml",
    "~/Views/Shared/{0}.cshtml",
    "~/Views/Shared/{0}.vbhtml"
};
PartialViewLocationFormats = new[] {
    "~/Views/{1}/{0}.cshtml",
    "~/Views/{1}/{0}.vbhtml",
    "~/Views/Shared/{0}.cshtml",
    "~/Views/Shared/{0}.vbhtml"
};
like image 28
SLaks Avatar answered May 16 '23 07:05

SLaks