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 foun开发者_如何学编程d... 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:
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" }
);
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.
Try add following route in global.asax:
context.MapRoute(
"default",
"Some/{controller}/{action}/",
new { controller = "Thing", action = "Index"}
);
Make sure that you have a file called SomeAreaRegistration.cs on your "Some" area. this file should contain something like the following:
public class SomeAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Some";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Some_default",
"Some/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
When using areas, put your index.cshtml at location ~/Areas/Some/Views/Thing/Index.cshtml
Did you check (by setting breakpoint) if the controller method is called?
The pages you listed where the view is searched are not in the area "some". From where do you call the link?
If you call the link from another area or from root you have to set the area in the action link:
@Html.ActionLink("Go To Some/Thing", "Index", "Thing", new {area="Some"}, null)
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.
Try this in RouteConfig.cs.
May be it will be helpful to someone..
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new {controller = "Controllername", action = "Actionname", id = UrlParameter.Optional },
namespaces: new [] { "Projectname.Areas.Areaname.Controllers" }
).DataTokens.Add("area", "Areaname");
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.
精彩评论