I'm using multiple areas in MVC 3 and I'm having problems with my views not being found. The routing seems to pick up my controllers correctly (all the actions are executing without any problems), but when I return a view MVC simply doesnt find it.
So if I have a simple controller called 'Thing' in an area called 'Some' and I do the following...
public ActionResult Index()
{
return View("Index");
}
The action is executed correctly, but MVC doesn't find the view and I'll get a message saying something like
The view 'Index' or it's master was not found... And it will show me all the searched locations, which will be
~/Views/Thing/Index.cshtml ~/Views/Shared/Index.cshtml
etc, etc, but it doesn't look in
~/Some/Views/Thing/Index.cshtml
Any ideas on what I am doing wrong?
Ok, sorry to have to answer my own question but nobody really gave me the answer I was looking for. It seems my problem was with custom routing.
To recreate the problem, I created a blank MVC 3 project and added an Area called 'Some' and a controller in that area called 'Thing'. On thing I created an Index action which simply returned a view. I then added the Index view to ~/Areas/Some/Views/Thing/Index.cshtml
Great. So when I hit /Some/Thing/Index it returns the view correctly.
Now go and add a route to Global.asax that looks like this:
Now when I navigate to /Bob I get the error I mentioned - MVC doesn't find the view. To fix this problem I had to register this route in the SomeAreaRegistration class instead of Global.asax. I also didn't need the 'area' property, so it looks like this.
Just to add another solution here. I was also having this problem but mine was due to having a conflicting "catch all" route in Global.asax.cs
Removing this route fixed the issue.
Make sure that you have a file called SomeAreaRegistration.cs on your "Some" area. this file should contain something like the following:
When using areas, put your index.cshtml at location ~/Areas/Some/Views/Thing/Index.cshtml
It'll not look in *~Some/*Views..... by default (I am not sure how you can force that either), the convention would be ~/Views/......, so that'd be the right place to put the view in. In case you want the URL to contain "Some", you can change the routing to handle that.
If your controller has the same name as the area, your controller will be picked up by the default base route
{controller}/{action}
BEFORE it checks the area route and therefore will look for the view in the root /views instead of in the area /views. Renaming either the area or the controller will resolve this.