我正在尝试在 MVC 5 网络应用中实施替代路由。
我有控制器代码:
namespace MyMvcProject.Web.Controllers
{
[RoutePrefix("account")]
public class AccountController : Controller {
[Route("{param}")]
[Authorize]
public ActionResult Index(string param = null) {
...
在点击网址时效果很好:http://example.com/account/testparam
。
但是,我希望能够将值param
作为可选参数。
我尝试将[Route("{param}")]
更改为[Route("{param}*")]
,但从未输入Index()
方法。我也尝试将其更改为[Route("{param:string=Test}")]
,但我遇到了一个使用术语string
的路由运行时错误。
我的RoutConfig.cs
包含:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{param}",
defaults: new { controller = "Home", action = "Index", param = UrlParameter.Optional }
);
}
有没有人知道如何使用这种替代路由语法强制Index()
拥有可选参数?它在我的应用的其他部分非常有用,所以我想保留RoutePrefix
和Route
装饰器。
更新
我还在尝试解决这个问题,所以我将路线装饰器更改为[Route("{param:int=0}")]
,将构造函数更改为public ActionResult Index(int id)
,它按预期工作(即http://example.com/account
行为就像输入http://example.com/account/0
一样。这正是我想要的,只使用string
数据类型。
当我将装饰器更改为:[Route("{id:string=\"\"}")]
并将构造函数更改为public ActionResult Index(string id)
时,我看到了运行时错误:
类型' DefaultInlineConstraintResolver'的内联约束解析器无法解决以下内联约束:' string'。
答案 0 :(得分:6)
找到答案here。我需要使用param
使?
成为可空的。
[Route("{param?}")]
[Authorize]
public ActionResult Index(string param = null) {
...
}
希望这将有助于将来的某些人。 我在这个主题上找不到很多参考文献。
答案 1 :(得分:6)
@ Brett 答案很棒:将?
添加到Route属性中的参数,然后在Action签名中提供默认值允许该参数是可选的。
这是Mike Wasson在Attribute Routing in Web API 2上发表的精彩文章,其中包括一篇关于可选参数的文章。
迈克还谈到应用多个约束,并说:您可以对参数应用多个约束,用冒号分隔。
[Route("users/{id:int:min(1)}")] public User GetUserById(int id) { ... }
这也很有效...直到你想要多个约束和一个可选参数。
我们知道,应用?
允许参数是可选的。因此,采用上面的例子,人们可能会认为
[Route("users/{id:int?:min(1)}")]
public User GetUserById(int id = 1) { ... }
将id
参数约束为大于0的整数,或为空(在这种情况下,使用默认值1)。实际上,我们收到错误消息:
类型' DefaultInlineConstraintResolver'的内联约束解析器无法解决以下内联约束:' int?'。
事实证明,约束的顺序很重要!只需在所有其他约束之后放置可选约束?
就可以得到预期的行为
[Route("users/{id:min(1):int?}")]
public User GetUserById(int id = 1) { ... }
这也适用于2个以上的约束,例如
[Route("users/{id:min(1):max(10):int?}")]
public User GetUserById(int id = 1) { ... }