Mironline
Mironline

Reputation: 2799

ASP.NET MVC 3 Routing Issue

the result of using default routing in asp.net mvc and using ActionLink

@Html.ActionLink("title", "Index", "Question", new { id = 25}, null)

is :

http://localhost/question/index/25

for changing the link to

http://localhost/question/25

I've added new routing roles in Global.asax before default :

routes.MapRoute(
            "default2", // Route name 
            "Question/{id}", // URL with parameters
            new { controller = "Questions", action = "Index", id = UrlParameter.Optional} // Parameter defaults
        );

I have the same Issue for users , tags , .... , Should I create the same role for each of theme ?

Upvotes: 0

Views: 203

Answers (2)

VJAI
VJAI

Reputation: 32768

Have you tried this?

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

UPDATE:

If the id is always going to be an integer then you can put a simple numeric constraint in the above route to avoid the routing issue reported by @Nick.

  routes.MapRoute(
      "my-route",
      "{controller}/{id}",
      new { controller = "Home", action = "Index", id = UrlParameter.Optional },
      new { id = @"\d*" }
  );

Upvotes: 2

Nick Bork
Nick Bork

Reputation: 4841

I figured I would take this one step further and show you how to create a route constraint so you didn't need to register three seperate routes.

Using the following article as a guide you can create a constraint that will validate the current routes Controller against a list of controllers you will specify:

http://www.asp.net/mvc/tutorials/controllers-and-routing/creating-a-custom-route-constraint-cs

So here is my class with the route constraint:

public class ControllerConstraint : IRouteConstraint
{
    private string[] _controllers;

    public ControllerConstraint() : this(null) { }
    public ControllerConstraint(string[] controllers)
    {
        _controllers = controllers;
    }

    #region IRouteConstraint Members
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        string  currentController = values.ContainsKey("controller")?  values["controller"].ToString() : null;

        return _controllers != null //The list of controllers passed to the route constraint has at least one value in it
            && !String.IsNullOrEmpty(currentController) //The current route data has a controller in it to compare against
            && (from c in _controllers where c.Equals(currentController,StringComparison.CurrentCultureIgnoreCase) select c).ToList().Count > 0; //We find a match of the route controller against the list of controllers
    }
    #endregion
}

From there all you need to do is modify how you register your route in the Globa.asax

 routes.MapRoute(
      "Action-less Route", // Route name
      "{controller}/{id}", // URL with parameters
      new { controller = "Questions", action = "Index", id = UrlParameter.Optional}, //Parameter defaults
      new {isController = new ControllerConstraint(new string[] {"Questions","Users","Tags"})} //Route Constraint
        ); 

You could also take it a step further and validate that {id} was a number with an additional route constraint like the following:

http://www.asp.net/mvc/tutorials/controllers-and-routing/creating-a-route-constraint-cs

Upvotes: 1

Related Questions