Search code examples
c#asp.net-mvcroutesasp.net-mvc-routingmaproute

Since I wrote a route for a specific Action of a Controller, do I need to write a route for all Actions inside the Controller?


I'm writing few routes for my MVC application. I have the following routes for my application:

routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Pages", action = "Index", id = UrlParameter.Optional }
            );

The route above is used when I want to access default values like:

www.servicili.com/budget/edit/1

www.servicili.com/professional/view/234

But, I create the following route for a specific purpose:

routes.MapRoute(
                name: "Perfil",
                url: "{UsuApelido}",
                defaults: new { controller = "Perfil", action = "Index"}
            );

the route above, is used to access the URL profile of a "plumber" for example: www.servicili.com/MarkZuckberg

the profile details are on the controller Perfil and Action Index, however, since I wrote this route, all other actions aren't working.

For example: If I try to access the Index action inside another controller, it redirect to Index of Perfil.

-- The question is: Since I wrote a route for a specific Action of a Controller, do I need to write a route for all Actions inside the Controller?


Solution

  • To solve your problem try like this,

    First define constraint,

    public class PlumberUrlConstraint: IRouteConstraint
    {
       public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
       {
          var db = new YourDbContext();
          if (values[parameterName] != null)
          {
            var UsuApelido = values[parameterName].ToString();
            return db.Plumbers.Any(p => p.Name == UsuApelido);
          }
          return false;
       }
    }
    

    Define two routes, put "Default" route at 2nd position

    routes.MapRoute(
                name: "Perfil",
                url: "{*UsuApelido}",
                defaults: new { controller = "Perfil", action = "Index"},
                constraints: new { UsuApelido = new PlumberUrlConstraint() }
            );
    
    routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Pages", action = "Index", id = UrlParameter.Optional }
            );
    

    Now if you have an 'Index' action in 'Perfil' Controller, you can get plumber name like this,

    public ActionResult Index(string UsuApelido)
    {
      //load the content from db with UsuApelido
      //display the content with view
    }
    

    Hope this help.