MVC Areas - View not found
Asked Answered
V

8

14

I have a project that is using MVC areas. The area has the entire project in it while the main "Views/Controllers/Models" folders outside the Areas are empty barring a dispatch controller I have setup that routes default incoming requests to the Home Controller in my area.

This controller has one method as follows:-

public ActionResult Index(string id)
    {
        return RedirectToAction("Index", "Home", new {area = "xyz"});
    }   

I also have a default route setup to use this controller as follows:-

routes.MapRoute(
            "Default",                                              // Default route
            "{controller}/{action}/{id}",
            new { controller = "Dispatch", action = "Index", id = UrlParameter.Optional }
        );   

Any default requests to my site are appropriately routed to the relevant area. The Area's "RegisterArea" method has a single route:-

context.MapRoute(
            "xyz_default",
            "xyz/{controller}/{action}/{id}",
            new { action = "Index", id = UrlParameter.Optional }

My area has multiple controllers with a lot of views. Any call to a specific view in these controller methods like "return View("blah"); renders the correct view. However whenever I try and return a view along with a model object passed in as a parameter I get the following error:-

Server Error in '/DeveloperPortal' Application.
The view 'blah' or its master was not found. The following locations were searched:
~/Views/Profile/blah.aspx
~/Views/Profile/blah.ascx
~/Views/Shared/blah.aspx
~/Views/Shared/blah.ascx 

It looks like whenever a model object is passed in as a param. to the "View()" method [e.g. return View("blah",obj) ] it searches for the view in the root of the project instead of in the area specific view folder.

What am I missing here ?

Thanks in advance.

Vaden answered 12/4, 2010 at 18:57 Comment(0)
V
8

Solved ! A couple of my "RedirectToAction" calls were not specifying the area name explicitly in the routeobject collection parameter of that method. Weird though, that that is required even though the controllers Redirecting are all in the same area. Also, the HtmlActionLinks work fine when I don't specify the new {area="blah"} in its routeobject collection, so I wonder why the controller action calls to RedirectToAction() need that even though both the calling and the called controller actions are all within the same area.

Vaden answered 13/4, 2010 at 20:14 Comment(1)
I had a similar issue. In my case my link did not have the area name in the path and even though the correct controller was called, the view could not be found. That situation leaves me with the question of how the controller got called.Alexandrina
C
7

If you use instead of

context.MapRoute(
        "xyz_default",
        "xyz/{controller}/{action}/{id}",
        new { action = "Index", id = UrlParameter.Optional }

use

context.MapRoute(
        "xyz_default",
        "{controller}/{action}/{id}",
        new { action = "Index", id = UrlParameter.Optional }

in your

xyzAreaRegistration.cs

then you don't need to explicitly specify your area in any link...

Cuman answered 18/11, 2013 at 8:54 Comment(2)
This sort of worked for me but with another problem. The route is hitting the correct controller but the view is not found (It's looking in the main project directory for the default view instead of in the area, which is what I need).Historiated
@jSideris i am having same issue. how did you solved this issue?Hesketh
T
5

Add the RouteArea attribute on the Controller class so MVC knows to use the "XYZ" Area for the views (and then you can set the AreaPrefix to empty string so routes do not need to start with "XYZ").

[RouteArea("Xyz", AreaPrefix = "")]
public class XyzController : Controller   
{
...
}
Tamica answered 8/3, 2017 at 17:45 Comment(0)
K
4

If this is a routing problem, you can fix it by registering your area routes first. This causes the routing engine to try matching one of the area routes, before matching a root route:

AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);

If I force an error by renaming one of my views folders in my areas application, I get a different error than yours:

The view 'Index' or its master was not found. The following locations 
  were searched:

~/Areas/xyz/Views/Document/Index.aspx
~/Areas/xyz/Views/Document/Index.ascx
~/Areas/xyz/Views/Shared/Index.aspx
~/Areas/xyz/Views/Shared/Index.ascx

...and then the usual root view folders.. 

..which is the pattern of subdirectories it would search if it thought it was in an area.

Kick answered 12/4, 2010 at 20:44 Comment(16)
That is done by default in an ASP.NET MVC 2 web application in VS2008. It is part of the default setup of the global.asaxVaden
Hi Robert, I re-checked all my controller namespaces. They all align with what they should be which is ProjectName.Areas.AreaName.Controllers.Vaden
The error you are getting is exactly what I am faced with. The only difference being that I actually have the pertinent views present in the area specific view folderVaden
Perhaps you could new up a RouteValueDictionary in the controller like this: System.Web.Routing.RouteValueDictionary routeData = RouteData.Tokens, set a breakpoint, hover over the routeData variable, and see if you're getting an area key with the value xyz? That would verify that the route data is correct.Kick
Note that the error you posted is not the same error I posted. The error I posted actually tries 8 different locations (4 for the area, and 4 for the root).Kick
Basically what I have done is that I had a standard MVC project that I moved in to an area when I migrated to MVC 2.0 So now the root folders are empty barring the controllers that have one root controller that is used to dispatch default requests to the Area that my project now lies under.Vaden
The global.asax has one route :- routes.MapRoute( "Default", // Default route "{controller}/{action}/{id}", new { controller = "Dispatch", action = "Index", id = UrlParameter.Optional } ); And the Area "xyz" has its default (even though this area has multiple controllers and views):- context.MapRoute( "Developers_default", "Developers/{controller}/{action}/{id}", new { action = "Index", id = UrlParameter.Optional } );Vaden
For some context, I do have a home controller in the root of my application for the initial (default) home Url. It performs a RedirectRoute into an area (specifying the name of the area route), and I stay in that area (or one of the other areas) for the remainder of the session. I only use root controllers for authentication.Kick
I'm sorry what are you referring to ? I have controllers only in the area, other than the dispatch controller in the root. When I debug the project, the controllers in the area are the ones getting called. However for some reason when I try to return a View MVC tries to search for that view under the root views folders.Vaden
Mind you, I don't use UrlParameter.Optional (not yet, anyway), and I think that might figure in here somehow.Kick
Yes, this is exactly what I am doing. The dispatch controller is like your root home controller. It performs a redirect to action to a specific controller and an action in the area.Vaden
I could do a redirecttoroute instead of a redirecttoaction.Vaden
What I am saying is that I think it will work if you use RedirectToRoute instead of RedirectToAction in your dispatch controller.Kick
Nope, that didn't work. I had a redirect to action in my DispatchController "Index" action which I now turned in to return RedirectToRoute("xyz_default",new{controller="Home", action = "Index"}); I get the same error.Vaden
Your master page. Should it be in the root views/shared folder or in the area specific views/shared folder ?Vaden
My master page is in the root. Currently I am using it for all views.Kick
D
2

Check the generated code at MyAreaAreaRegistration.cs and make sure that the controller parameter is set to your default controller, otherwise the controller will be called bot for some reason ASP.NET MVC won't search for the views at the area folder

public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            "SomeArea_default",
            "SomeArea/{controller}/{action}/{id}",
            new { controller = "SomeController", action = "Index", id = UrlParameter.Optional }
        );
    }
Delaminate answered 6/6, 2010 at 20:7 Comment(1)
Thanks! This fixed it for me with an ASP.NET MVC 5 scaffold.Leah
F
2

For those who are looking for .net core solution please use

 app.UseMvc(routes =>
    {
      routes.MapRoute(
        name : "areas",
        template : "{area:exists}/{controller=Home}/{action=Index}/{id?}"
      );
    });`

If you have some code in main project and some code in areas use the following code.

app.UseMvc(routes => {
            routes.MapRoute(
                name: "areas",
                template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });

Note make sure you have areas defined in your controller

 [Area("Test")]
public class TestController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}

}

Fowl answered 3/10, 2019 at 15:28 Comment(1)
was missing [Area("Test")] and stuck for hours.Admittedly
S
1

I just had the same problem and solved it by setting the ascx's 'Build Action' property to 'Embedded Resource'.

Stunner answered 10/12, 2010 at 14:19 Comment(0)
P
1

Try this code. Do changes in Area Registration File...

context.MapRoute(
    "YourRouteName",   // Route name //
    "MyAreaName/MyController/{action}",   // URL with parameters //
    new { 
        controller = "MyControllerName", 
        action = "MyActionName", meetId =  UrlParameter.Optional
     },   // Parameter defaults
    new[] { "Your Namespace name" }
);
Pancreas answered 29/6, 2012 at 10:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.