Reputation: 762
I really don't know what title should I use to describe my problem. To simplify my problem. Here is my test. I create a mvc3 site from scratch. I then add area called "admin". Inside admin, I have a controller named "Search" and has "Authorize" attribute decorated. I then changed my Global.ascx.cs route setting to append my controller namespace. Now I start my test.
Question 1
When I am accessing to http://localhost:xxx/Search page, it redirects me back to /Account/Logon page, it makes me confuse first, why it redirects me to logon page? it shouldn't reach to Admin search controller at all as I understand. If I removed the Authorize attribute, it display the yellow screen said can't find the view as I expected.
Question 2
If I add Authorize attribute with role, e.g. (Roles="Admin"), then I try access to Search page again, no matter login succeed or not, I always get redirect back to logon page. Why it doesn't give me the yellow screen, coz I am trying to request the search controller index view in the main site not the admin area's one. quite confuse.
I am a newbie in MVC development, can someone give me a solution regarding to my problem?
Thanks
Global.ascx.cs
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new string[]{"TestAreaRouting.Controllers"}
);
}
Upvotes: 1
Views: 867
Reputation: 1039160
You could constrain the default controller factory to look only inside the specified namespace for controllers in the RegisterRoutes
method of Global.asax
by setting the UseNamespaceFallback
data token to false
:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new string[] { "TestAreaRouting.Controllers" }
).DataTokens["UseNamespaceFallback"] = false;
}
If you don't do this when you request /search
the admin
area route doesn't match because the url doesn't start with the Admin
prefix.
So it is the default route that matches. The default controller factory starts scanning the assembly for a class called SearchController
that derives from Controller
and since it finds one it instantiates it and uses it to serve the request. Obviously it doesn't find a corresponding Index view because it looks in ~/Views/Search/Index.cshtml
which obviously doesn't exist. The actual view is located in the area.
Now that we have constrained the controllers to their respective locations you could decorate them with the Authorize attribute and it should behave consistently.
Upvotes: 1