Reputation: 146
I am starting to use EditorFor helper method to render my razor partial views, but I couldn't get the partials in the Areas folder to work.
Here is the path to the partial:
~\Areas\Products\Views\Shared\EditorTemplates\_Edit.cshtml
The partial is really simple with only one "div" tag to do the testing.
Try to use in my page view (~\Areas\Products\Views\EditPage.cshtml) as
@Html.EditorFor(m => m.ProductEditModel, "_Edit")
Visual studio tells me that "Cannot resolve template '_Edit'".
Now, if I move the partial to the root view folder:
~\Views\Shared\EditorTemplates\_Edit.cshtml
It works, Visual studio has no problems to resolve the template, and the div is renderred correctly in my browser.
I also tried to customize the RazorViewEngine, did not work either
namespace MySite.Web
{
public class RazorViewEngine : System.Web.Mvc.RazorViewEngine
{
public RazorViewEngine()
: this(null)
{
}
public RazorViewEngine(IViewPageActivator viewPageActivator)
: base(viewPageActivator)
{
AreaPartialViewLocationFormats = new[]
{
"~/Areas/{2}/Views/Shared/EditorTemplates/{0}.cshtml"
}.Union(AreaPartialViewLocationFormats).ToArray();
}
}
}
Just wondering what did I do wrong? BTW, I am using MVC3 at the moment, can't upgrate to MVC4 due to some old components.
Upvotes: 1
Views: 1830
Reputation: 146
I am answering my own question now.. My page view path was not correct. Since my area is Products, controller is ProductController, my page view should be placed in ~\Areas\Products\Views\Product\EditPage.cshtml, that way, it matches what the view engine expects, and the partial will be corrected resolved.
Upvotes: 0
Reputation: 11
When calling a partial view or view from a different area in MVC, specify the full path of the partial view or view. Since MVC is based on convention, by convention it will look in the same area the calling code in the view (or controller) resides for any partial views or views referenced, unless a specific path is used. Try using the full path to reference the partial view when it is located in the products area:
@Html.EditorFor(m => m.ProductEditModel, "~/Areas/Products/Views/Shared/EditorTemplates/_Edit.cshtml")
Since the view referenced is a shared view it doesn't matter if you specify the full path if you are in the same area. However, if you are trying to access a view within a different directory than the view trying to reference it and this directory is not named shared you will need to specify the full path regardless of area. It is similar when the controller calls the view; if a controller from the same area as the referenced view specifies the short name for the view and this view is from a parent directory named different than its own (ignoring the "controller" suffix) the view engine will not find your view. Unless of course the parent directory for the view is in the shared folder.
Whether it's in the controller or a view you can't use the "short name" across areas because the view engine has a convention for where to look when the path isn't used. Areas are meant to do this to keep your code separated, or decoupled if you will, at a high level by default. So any decision to "cross the barrier" should be thought about mindfully, but certainly not discouraged. It's all about convention.
Upvotes: 1