8

我想使用默认控制器 = Home 和默认操作 = 索引来维护 ASP.NET MVC 4 的现有控制器/动作/id 路由,但也允许控制器/id 路由到控制器的索引方法,只要第二项不是一个已知的动作。

例如,给定一个具有 Index 和 Send 动作的控制器 Home:

/Home/Send -> controller's Send method
/Home -> controller's Index method
/Home/Send/xyz -> controller's Send method with id = xyz
/Home/abc -> controller's Index method with id = abc

但是,如果我先定义任一路线,它会隐藏另一条路线。我该怎么做?

4

6 回答 6

5

在默认通用之前先执行特定的。顺序很重要。

routes.MapRoute(name: "single", url: "{controller}/{id}",
    defaults: new { controller = "Home", action = "Index" }, 
    constraints: new { id = @"^[0-9]+$" });

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home",
    action = "Index",
    id = UrlParameter.Optional }
);
于 2012-12-11T19:26:25.933 回答
2

如果您的操作列表(例如Send)是众所周知的,并且它们的(操作)名称不能与某些 ID 值相同,我们可以使用我们的自定义 ConstraintImplementation:

public class MyRouteConstraint : IRouteConstraint
{
  public readonly IList<string> KnownActions = new List<string> 
       { "Send", "Find", ... }; // explicit action names

  public bool Match(System.Web.HttpContextBase httpContext, Route route
                  , string parameterName, RouteValueDictionary values
                  , RouteDirection routeDirection)
  {
    // for now skip the Url generation
    if (routeDirection.Equals(RouteDirection.UrlGeneration))
    {
      return false; // leave it on default
    }

    // try to find out our parameters
    string action = values["action"].ToString();
    string id = values["id"].ToString();

    // id and action were provided?
    var bothProvided = !(string.IsNullOrEmpty(action) || string.IsNullOrEmpty(id));
    if (bothProvided)
    {
      return false; // leave it on default
    }

    var isKnownAction = KnownActions.Contains(action
                           , StringComparer.InvariantCultureIgnoreCase);

    // action is known
    if (isKnownAction)
    {
      return false; // leave it on default
    }

    // action is not known, id was found
    values["action"] = "Index"; // change action
    values["id"] = action; // use the id

    return true;
  }

并且路线图(在默认路线图之前 - 必须同时提供)应该如下所示:

routes.MapRoute(
  name: "DefaultMap",
  url: "{controller}/{action}/{id}",
  defaults: new { controller = string.Empty, action = "Index", id = string.Empty },
  constraints: new { lang = new MyRouteConstraint() }
);

摘要:在这种情况下,我们正在评估“action”参数的值。

  • 如果 1) action 和 2) id 都提供了,我们不会在这里处理。
  • 也不是已知的动作(在列表中,或反映......)。
  • 仅当动作名称未知时,让我们更改路由值:将动作设置为“索引”,将动作值设置为 ID。

注意:action名称和id值必须是唯一的......然后这将起作用

于 2012-12-12T07:15:46.323 回答
1

最简单的方法是在 Controller 中简单地创建两个 Action 方法。一个用于索引,一个用于发送,并将您的字符串 id 参数放在两者上。由于您不能拥有重复或重载的操作方法,因此可以解决该问题。您的 Index 方法现在将处理 id 存在或不存在(null)的索引或空白路径,并以这种方式处理您的视图。您的 Send 方法将与 Index 完全相同。然后,您可以根据 id 是否为空来按您喜欢的方式路由、处理或重定向。这应该在不更改 RouteConfig.cs 的情况下工作:

public ActionResult Index(string id) {if (id == null) Do A else Do B}

public ActionResult Send(string id) {if (id == null) Do A else Do B}

我为此挣扎了很长时间,这是最简单的解决方案。

于 2017-07-01T11:08:34.753 回答
0

这对我有用:

1)在RouteConfig中,我把它放在第一行:

routes.MapRoute(name: "single", url: "{controller}/{lastName}",
            defaults: new { controller = "LeaveRequests", action = "Index" });

2)在我的控制器中:

public ViewResult Index(string lastName)
{
    if (lastName == null)
    {
        return //return somthing
    }
    else
    {
        return //return something
    }
 }

3)当你调用控制器时

http://localhost:34333/leaveRequests/Simpsons

它会给你所有对辛普森一家的要求。

如果你打电话给http://localhost:34333/leaveRequests/ 它会给出所有请求

于 2013-08-10T16:48:38.917 回答
0

我认为没有满足您要求的解决方案,因为您有两条竞争路线。也许您可以定义一些特定的东西(如果您没有任何其他控制器)。

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

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

routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index",
                                               id = UrlParameter.Optional }
    );
于 2012-12-11T22:06:02.967 回答
0

这对我有用

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
            name: "Default1",
            url: "{id}",
            defaults: new { controller ="Home", action ="Index" }
        );
routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller ="Home", action ="Index", id = UrlParameter.Optional }
        );
于 2016-03-28T15:06:10.363 回答