The entire need to have custom view locations started when I implemented my Component controllers as separate classes.
By default DD4T .net comes (or expects) one ComponentController class. In the Component Template metadata, we can specify the controller, action and view names to execute and use when DD4T renders a Component Presentation on this Component Template.
Since I have several Component controllers, for the sake of clarity and separation, I implemented several controller classes -- one for each Component controller I have. For example, I have a DeviceController that renders Component Presentations based on Schema Device.
DeviceController defines a simple Index method that is mapped from the Component Template metadata.
The moment I executed my code, I got nice and glorious InvalidOerationException stating that .NET MVC can't find my "Device.cshtml" view (which I had also mapped from the Component Template metadata):
It seems the MVC view render engine expects my view inside a folder with the same name as the controller (i.e. in my case /Views/Device).
I would rather have all my Component views under folder ~/Views/Component and Page views under ~/Views/Page. Then all my partial views are under ~/Views/Shared.
It turns our the RazorViewEngine has a series of preconfigured search location patterns that it uses when looking for the view corresponding to a controller. All I had to do was to define my own search location patterns to use ~/Views/Component/, ~/Views/Page/ and ~/Views/Shared/. This can be done in the Global.asax.cs class, inside method OnApplicationStarted, by setting the RazorViewEngine property ViewLocationFormats:
By default DD4T .net comes (or expects) one ComponentController class. In the Component Template metadata, we can specify the controller, action and view names to execute and use when DD4T renders a Component Presentation on this Component Template.
Since I have several Component controllers, for the sake of clarity and separation, I implemented several controller classes -- one for each Component controller I have. For example, I have a DeviceController that renders Component Presentations based on Schema Device.
DeviceController defines a simple Index method that is mapped from the Component Template metadata.
public class DeviceController : MyControllerBase { public ActionResult Index(int? publication, int? component, string view) { // code goes here } }
The moment I executed my code, I got nice and glorious InvalidOerationException stating that .NET MVC can't find my "Device.cshtml" view (which I had also mapped from the Component Template metadata):
[InvalidOperationException: The view 'Device' or its master was not found or no view engine supports the searched locations. The following locations were searched: ~/Views/Device/Device.aspx ~/Views/Device/Device.ascx ~/Views/Shared/Device.aspx ~/Views/Shared/Device.ascx ~/Views/Device/Device.cshtml ~/Views/Device/Device.vbhtml ~/Views/Shared/Device.cshtml ~/Views/Shared/Device.vbhtml]
It seems the MVC view render engine expects my view inside a folder with the same name as the controller (i.e. in my case /Views/Device).
I would rather have all my Component views under folder ~/Views/Component and Page views under ~/Views/Page. Then all my partial views are under ~/Views/Shared.
It turns our the RazorViewEngine has a series of preconfigured search location patterns that it uses when looking for the view corresponding to a controller. All I had to do was to define my own search location patterns to use ~/Views/Component/, ~/Views/Page/ and ~/Views/Shared/. This can be done in the Global.asax.cs class, inside method OnApplicationStarted, by setting the RazorViewEngine property ViewLocationFormats:
protected override void OnApplicationStarted() { RazorViewEngine razorEngine = ViewEngines.Engines.OfType<RazorViewEngine>().First(); razorEngine.ViewLocationFormats = new string[] { "~/Views/Component/{0}.cshtml", "~/Views/Page/{0}.cshtml", "~/Views/Shared/{0}.cshtml" }; }
Comments