0

I'm trying to understand how the route config works in the MVC 5.

I have the following structure for my application:

BaseCRUDController

public class BaseCRUDController<TEntity, TEntityViewModel> : Controller 
    where TEntity : class
    where TEntityViewModel : class
{
    private readonly IBaseService<TEntity> baseService;

    public BaseCRUDController(IBaseService<TEntity> service)
    {
        this.baseService = service;
    }

    [HttpGet]
    public virtual ActionResult Index()
    {
        IList<TEntityViewModel> entities = baseService.FindFirst(10).To<IList<TEntityViewModel>>();
        return View(entities);
    }

}

CountriesController

[RouteArea("management")]
[RoutePrefix("countries")]
public class CountriesController : BaseCRUDController<Country, CountryViewModel>
{
    private readonly ICountryService service;

    public CountriesController(ICountryService service) 
        : base(service)
    {
        this.service = service;
    }
}

What I'm trying to do is simple: http://myapplication.com/management/countries. I have many others controllers that the superclass is the base controller. I'm doing this way to avoid code repetition, since that the controllers have similar structure.

The problems are:

  • I can't reach the url that I want (/management/countries)
  • I don't know how to configure my Home Controller, because I want that it could be reached by http://myapplication.com

How could I fix these problems?

My route config is like that:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapMvcAttributeRoutes();

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}
Guilherme Chiara
  • 1,154
  • 2
  • 12
  • 15

2 Answers2

0

After a little playing around I managed to get it to work.

The problem is when you are using attribute routing there are no default route parameters assigned.

For example in your Default route the defaults are controller = "Home", action = "Index". So if you were to call http://myapplication.com/ the routing engine will automatically default to /Home/Index/ and so on.

However the attribute route has no way of knowing you want to default to the Index action (or any other action for that matter).

To solve the issue add the Route attribute to the CountriesController like this:

[RouteArea("management")]
[RoutePrefix("countries")]
[Route("{action=Index}")] // this defines the default action as Index
public class CountriesController : BaseCRUDController<Country, CountryViewModel>
{
    private readonly ICountryService service;

    public CountriesController(ICountryService service) 
        : base(service)
    {
        this.service = service;
    }
}

Also for future reference Phil Haack's Route Debugger is extremely helpful for figuring out routing issues.

Brent Mannering
  • 2,316
  • 20
  • 19
0

Have you defined Area (management) for your controllers? if you try without Area, is that getting redirect properly?

nikudale
  • 399
  • 2
  • 12