Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC Routing with different Areas with multiple controllers

Tags:

c#

asp.net-mvc

My solution structure is the following:

Areas
    - Games
        -Controllers
        -Views etc
    - Movies
        -Controllers
            - MoviesController.cs
            - MovieCalendarController.cs
            - MovieSearchController.cs
        -Views etc

Now what I would like is to be able to do this: Navigate to https://localhost/Movies/ and hit the index of the MoviesController.cs

Navigate to: https://localhost/Movies/Calendar/ and hit the index of the MovieCalendarController.cs

And lastly navigate to https://localhost/Movies/Search/ and hit the index of the MovieSearchController.cs

What I have tried but is not working (getting No route in the route table matches the supplied values.) errors:

MovieAreaRegistration.cs

public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute(
                "Movies_default",
                "Movies/{action}/{id}",
                new { controller = "Movies", action = "Index", id = UrlParameter.Optional }
            );

            context.MapRoute(
                "Calendar_default",
                "Movies/Calendar/",
                new { controller = "MovieCalendar", action = "Index", id = UrlParameter.Optional }
            );


            context.MapRoute(
                "Search_default",
                 "Movies/Search/{action}/{id}",
                    new { controller = "MovieSearch", action = "Index", id = UrlParameter.Optional }
            );
        }

Apologies, I'm new to areas and routing

Update

After using attribute routing I have fell into this problem:

Multiple controller types were found that match the URL. This can happen if attribute routes on multiple controllers match the requested URL.

The request has found the following matching controller types: MovieCalendar.UI.Areas.Movies.Controllers.MovieCalendarController MovieCalendar.UI.Areas.Movies.Controllers.MoviesController

Movies Controller

[RouteArea("Movies")]
[Route("{action}")]
public class MoviesController : BaseController
{
}

Calendar Controller

[RouteArea("Movies")]
[RoutePrefix("Calendar")]
[Route("{action=Index}")]
public class MovieCalendarController : BaseController
{
}

This happens when accessing the url http://localhost/Movies/Calendar hoping it will take me to the MovieCalendarController Index action method. I can see why it's complaining because there could be a ActionMethod in the MovieController called Calendar (There is not).

like image 267
Jamie Rees Avatar asked Jul 20 '15 16:07

Jamie Rees


People also ask

Can we have multiple controllers in MVC?

In Spring MVC, we can create multiple controllers at a time. It is required to map each controller class with @Controller annotation.

Can two different controllers access a single view in MVC?

Yes. Mention the view full path in the View method. If the name of your Views are same in both the controllers, You can keep the Common view under the Views/Shared directory and simply call the View method without any parameter.

How many routes can be defined in the MVC 3 application?

there are no limits in creating routes. You can create as many route as you want in your RouteConfig.

What is dynamic routing in MVC?

What is Dynamic Routing? MVC Routing operates on the basis that a request is handled by Controllers and Actions in predefined routes. Dynamic Routing is where a request maps to a Page (TreeNode), and that Page's settings (Template, Page Type) determines how the request should be handled (which Controller/Action/View).


1 Answers

You may be better off with Attribute Routing. It will let you do this:

   public class MoviesController : Controller {

        [Route("Movies")]
        public ActionResult Index() {
            return this.View();
        }
    }

    public class MovieCalendarController : Controller {

        [Route("Movies/Calendar")]
        public ActionResult Index() {
            return this.View();
        }
    }

And then you can get rid of your current route mappings and use this initialize your routes:

RouteTable.Routes.MapMvcAttributeRoutes();

More information on attribute routing can be found here.

Update

[RouteArea("Movies")]
[Route("{action}")]
public class MoviesController : BaseController
{
}

This route will match urls starting with Movies/ followed by any string, including Calendar. So this route will clash with:

[RouteArea("Movies")]
[RoutePrefix("Calendar")]
[Route("{action=Index}")]
public class MovieCalendarController : BaseController
{
}

Convention based routing will be difficult with the naming convention your are using for your controllers.

like image 76
Anish Patel Avatar answered Sep 30 '22 16:09

Anish Patel