可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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?
回答1:
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" }
);
回答2:
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.
回答3:
Try add following route in global.asax:
context.MapRoute(
"default",
"Some/{controller}/{action}/",
new { controller = "Thing", action = "Index"}
);
回答4:
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 }
);
}
}
回答5:
When using areas, put your index.cshtml at location ~/Areas/Some/Views/Thing/Index.cshtml
回答6:
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)
回答7:
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.
回答8:
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.