Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC 3 does not look for views under Areas

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?

like image 819
Jaco Pretorius Avatar asked Jul 20 '11 13:07

Jaco Pretorius


3 Answers

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:

routes.MapRoute(
                "Custom", // Route name
                "Bob", // URL with parameters
                new { area = "Some", controller = "Thing", action = "Index" }
                );

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.

    context.MapRoute(
        "Custom", // Route name
        "Bob", // URL with parameters
        new { controller = "Thing", action = "Index" }
        );
like image 52
Jaco Pretorius Avatar answered Oct 21 '22 18:10

Jaco Pretorius


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.

like image 30
Despertar Avatar answered Oct 21 '22 17:10

Despertar


Try add following route in global.asax:

 context.MapRoute(
                "default",
                "Some/{controller}/{action}/",
                new { controller = "Thing", action = "Index"}
            );
like image 21
Yaroslav Bigus Avatar answered Oct 21 '22 17:10

Yaroslav Bigus