MVC ActionResult方法,参数如何匹配?

时间:2014-03-31 09:49:08

标签: c# asp.net-mvc

我会尽力尽力说出来。 假设我在控制器X中有一个方法:

Index(string someString)

这有效吗? :X /索引

还是我需要:X / Index / someString

(所有这些都使用默认路由配置)。

现在,是否可以使用第二种方法,以便:

Index(stringSomestring)
{
..
}

Index()
{
}

如果是这样,MVC路线如何选择正确的方法?

...最后

有什么区别: 在routeConfiguration或方法Parameters本身中声明参数默认值?

e.g。 :

rotes.Add("", "etcetc", new {someString = string.Empty);

VS

Index(string someString = string.Empty)

如果它太愚蠢或冗长,请表示感谢和抱歉。

----编辑----- 感谢您的响应anaximander,您帮助我清除了一些头脑(虽然仍在努力)。 考虑一下:

routes.MapRoute("",
                "Student/Sort-By{sortType}",
                new { controller="Student", action="Index", sortType= ""}
                );

我有一个方法:

Index(string sortType)
{
...
}

如果我提供网址:学生/排序日期 它工作正常。 如果我提供网址:学生/分拣 它找不到任何东西,虽然我的方法有一个空排序选项...

我觉得我过于复杂/做一些愚蠢的事情,但无法确定:(

2 个答案:

答案 0 :(得分:2)

这取决于您的路由设置。默认路由如下所示:

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

请注意UrlParameter.Optional部分。这意味着您可以转到somehost.com/X/Index,它会查找方法Index(),或者您可以添加另一个斜杠和参数,它会查找Index(foo id)其中foo是你喜欢的任何类型。

路线按您添加的顺序应用。这意味着,如果您从RouteConfig的顶部开始并向下读,那么第一个与URL匹配的就是它将使用的那个。这就是为什么你应该将更多特定路由置于以上的更普遍的路由 - 否则,一般路由将捕获所有URL并阻止使用更具体的路由。

系统查找:

  • 与URL的{controller}部分匹配的控制器(如果URL未指定,则为默认控制器)
  • 该控制器上与URL的{action}部分匹配的所有操作方法(如果URL未指定,则为默认操作)
  • 具有与从URL提取的参数集匹配的参数名称的任何方法,以及路径中指定的参数。
    • 这意味着对于方法Index(int id),如果网址包含{id}部分,则会使用该方法。如果该部分不存在,但路由指定了默认值,那么它将使用该方法的默认值。如果没有值,没有默认值,并且参数标记为UrlParameter.Optional,则会查找不需要id的其他方法。 (如果参数是必需的,则此路由不匹配,因为URL未提供一个。)
    • 如果系统无法决定您尝试拨打哪种方法,您将收到一个例外情况,告诉您该路线不明确。

因此,在您的情况下,如果您希望能够使用somehost.com/X/Index转到Index(string someString),那么您需要这样的路线:

routes.MapRoute(
    name: "Index",
    url: "{controller}/{action}/{someString}",
    defaults: new { controller = "X", action = "Index", someString = String.Empty }
);

如果URL没有给出,则使用空字符串调用Index(string someString)。如果您希望没有someString参数的网址转到Index,那么您可以设置somestring = UrlParameter.Optional,如果网址没有提供,则会查找不会不需要它。如果您完全保留someString超出默认值,那么任何未提供默认值的URL都将对此路由无效,并且必须与其他路径匹配。如果您仍然在底部获得了预先提供的默认路由,那么它将捕获somehost.com/X/Index,因为它符合该模板,因此它假设您已省略了可选的id参数并且看起来对于像Index()这样的方法。

修改

当组合URL fluff和这样的参数时,它会变得有点棘手。我无法自己运行调试,我猜想就系统而言,匹配Sort-By{sortType}时,字符串Sort-By不是"Sort-By" + "",它是{{1 }}。也就是说,URL不会将"Sort-By" + null的值作为空白字符串,因为空白字符串仍然是字符串,而此URL包含根本没有字符串< / em>在那个位置。如果URL未提供{sortType}的值且未标记为可选,则URL与此路由不匹配。这可能会更好:

{sortType}

或者,您可以考虑从URL中删除排序并使用查询参数,因此路由变为

routes.MapRoute("",
    "Student/Sort/{sortType}",
    new { controller="Student", action="Index", sortType= ""}
);

并排序,转到routes.MapRoute("", "Student/", new { controller="Student", action="Index", sortBy= ""} );

答案 1 :(得分:0)

您的路由不能有多个Index()

如果您想使用X / Index或X / Index / someText

您必须声明ActionResult索引(字符串someString)

路由进程将知道Index可以接受String,然后它将重定向到正确的操作。您不需要将字符串呈现为可空或指定空字符串。字符串将只是null。

To&#34; guess&#34;正确的行动我认为mvc框架使用反射并关联参数的类型和名称。

路由过程始终有效,但如果要指定与默认路径不同的路由,则必须:

rotes.Add("", "etcetc", new {someString = string.Empty);