Asp.net mvc 3 ASP.NET MVC 3路由问题

Asp.net mvc 3 ASP.NET MVC 3路由问题,asp.net-mvc-3,routing,Asp.net Mvc 3,Routing,在asp.net mvc中使用默认路由和使用ActionLink的结果 @Html.ActionLink("title", "Index", "Question", new { id = 25}, null) 是: 用于将链接更改为 http://localhost/question/25 在默认设置之前,我已在Global.asax中添加了新的路由角色: routes.MapRoute( "default2", // Route name

在asp.net mvc中使用默认路由和使用ActionLink的结果

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

用于将链接更改为

http://localhost/question/25
在默认设置之前,我已在Global.asax中添加了新的路由角色:

routes.MapRoute(
            "default2", // Route name 
            "Question/{id}", // URL with parameters
            new { controller = "Questions", action = "Index", id = UrlParameter.Optional} // Parameter defaults
        );
我对用户、标签等有相同的问题。我是否应该为每个主题创建相同的角色

你试过这个吗

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

如果
id
总是一个整数,那么您可以在上述路由中设置一个简单的数字约束,以避免@Nick报告的路由问题

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

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

如果
id
总是一个整数,那么您可以在上述路由中设置一个简单的数字约束,以避免@Nick报告的路由问题

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

我想我会更进一步,向您展示如何创建一个路由约束,这样您就不需要注册三个单独的路由

使用以下文章作为指导,您可以创建一个约束,该约束将根据您将指定的控制器列表验证当前路由控制器:

这是我的类和路由约束:

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
}
从这里开始,您只需修改在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
        ); 
您还可以进一步验证{id}是否是一个带有额外路由约束的数字,如下所示:


我想我会更进一步,向您展示如何创建路由约束,这样您就不需要注册三条单独的路由

使用以下文章作为指导,您可以创建一个约束,该约束将根据您将指定的控制器列表验证当前路由控制器:

这是我的类和路由约束:

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
}
从这里开始,您只需修改在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
        ); 
您还可以进一步验证{id}是否是一个带有额外路由约束的数字,如下所示:


是的,我试过了。但我认为这条路线直接影响到
表单
。我不知道为什么,但是当我使用此路径时,表单的
操作
属性为空!!!!如果使用此路由,{controller}/{action}/{id}的默认路由将永远不会匹配,因为您的新路由将始终是匹配的,并且每个URL都将查找索引操作。为了使此路由正常工作,您需要创建一个路由约束,以确保ID是有效的(数字值或它存在于数据库中)。但我认为这条路线直接影响到
表单
。我不知道为什么,但是当我使用此路径时,表单的
操作
属性为空!!!!如果使用此路由,{controller}/{action}/{id}的默认路由将永远不会匹配,因为您的新路由将始终是匹配的,并且每个URL都将查找索引操作。为了使此路由正常工作,您需要创建路由约束以确保ID有效(数值或数据库中存在该ID)。您在哪里添加了路由?如果将其添加到{controller}/{action}/{id}的默认MVC路由下方,则需要将其移动到默认路由上方。另外,你不能有两条同名的路线,所以我建议把这条路线叫做“问题”之类的。@NickBork,你说得对。我在
default
之前添加了此路由。名称不同(更新后),那么移动路由位置是否会导致ActionLink生成正确的ActionLink代码?如果是这样,您可以创建两个额外的路由,一个用于“用户”,另一个用于“标签”,或者您可以修改新路由,并使用路由约束进行一些筛选,以仅匹配“问题”、“用户”或“标签”,您在何处添加了路由?如果将其添加到{controller}/{action}/{id}的默认MVC路由下方,则需要将其移动到默认路由上方。另外,你不能有两条同名的路线,所以我建议把这条路线叫做“问题”之类的。@NickBork,你说得对。我在
default
之前添加了此路由。名称不同(更新后),那么移动路由位置是否会导致ActionLink生成正确的ActionLink代码?如果是这样的话,您可以创建两个额外的路由,一个用于“用户”,另一个用于“标签”,或者您可以修改新路由,并使用路由约束进行一些筛选,以仅匹配“问题”、“用户”或“标签”