ASP.NET 控制器映射中的 MVC 枚举参数
ASP.NET MVC enum argument in controller mapping
ASP.NET MVC 为控制器方法提供了简单的模板,例如 Details
,并且可以有类似的东西:
public ActionResult Details(int id)
{
// do something
}
可以通过以下方式访问:http://localhost:port/Controller/Details/id
我想做的是提供一种不同的类型,例如:
public enum MyEnum
{
All,
Pending,
Complete
}
然后我将我的控制器方法设置为:
public ActionResult MyMethod(MyEnum myEnum = MyEnum.Pending)
{
// do something
}
这适用于:http://localhost:port/Controller/MyMethod/
因为它使用默认参数。
要指定一个不同的参数,我必须做 http://localhost:port/Controller/MyMethod?myEnum=All
并且有效。
我想知道,我是否可以使用 http://localhost:port/Controller/MyMethod/All
而不是使用 ?myEnum=All
?
尝试这样做时,我得到了一个可以理解的 404
异常,但为什么 Details
中的 id
没有发生这种情况?
我可以更改当前 url: "{controller}/{action}/{id}"
的 MapRoute
以允许我使用自己的类型实现它吗?
到目前为止我尝试过的:
我只想为我的一个方案(例如 http://localhost:port/Controller/MyMethod/{ViewType}
)执行此路由实施,我尝试了 this 但它似乎没有做任何事情:
routes.MapRoute(
"MyRoute",
"MyController/Index/{MyEnum}",
new { controller = "MyController", action = "Pending" }
);
你确实可以。不要更改默认路由 "{controller}/{action}/{id}"
,而是在默认路由之前添加一个。这个新的需要相当具体:
routes.MapRoute(
"EnumRoute",
"Controller/MyMethod/{myEnum}",
new { controller = "Controller", action = "MyMethod", myEnum = UrlParameter.Optional }
);
基本上说的就是"when you see request to literally Controller/MyMethod/whatever, use this controller and that method and pass whatever as parameter of the request"。请注意,实际控制人不一定必须是 url 中所说的路线,尽管坚持这一点是个好主意。
/Controller/MyMethod/All
确实有效。问题在于默认路由,它将 All
视为 id
路由参数,这与您的操作用作参数的内容不一致。如果您的动作签名是:
,它实际上可以正常工作
public ActionResult MyMethod(MyEnum id = MyEnum.Pending)
因为它将 All
绑定到正确的东西。
您可以为此use-case添加另一条路线,但您需要注意不要只是创建另一条"default"路线, 它将接管。换句话说,您必须修复 URL:
的一部分
routes.MapRoute(
"MyCustomRoute",
"Controller/{action}/{myEnum}",
new { controller = "Controller", action = "MyMethod", myEnum = MyEnum.Pending }
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
然后,仅通过路由的 /Controller/
前缀,它将使用您的自定义路由,并为 myEnum
参数填写 All
,而不是点击默认路由并尝试填写 id
.
但是,请注意,当使用枚举作为路由参数时,它们必须完全匹配。因此,虽然 /Controller/MyMethod/All
有效,但 /Controller/MyMethod/all
无效。要解决这个问题,您必须创建一个自定义模型活页夹。我进行了快速搜索,找到了以下 article,可能会在这方面对您有所帮助。
ASP.NET MVC 为控制器方法提供了简单的模板,例如 Details
,并且可以有类似的东西:
public ActionResult Details(int id)
{
// do something
}
可以通过以下方式访问:http://localhost:port/Controller/Details/id
我想做的是提供一种不同的类型,例如:
public enum MyEnum
{
All,
Pending,
Complete
}
然后我将我的控制器方法设置为:
public ActionResult MyMethod(MyEnum myEnum = MyEnum.Pending)
{
// do something
}
这适用于:http://localhost:port/Controller/MyMethod/
因为它使用默认参数。
要指定一个不同的参数,我必须做 http://localhost:port/Controller/MyMethod?myEnum=All
并且有效。
我想知道,我是否可以使用 http://localhost:port/Controller/MyMethod/All
而不是使用 ?myEnum=All
?
尝试这样做时,我得到了一个可以理解的 404
异常,但为什么 Details
中的 id
没有发生这种情况?
我可以更改当前 url: "{controller}/{action}/{id}"
的 MapRoute
以允许我使用自己的类型实现它吗?
到目前为止我尝试过的:
我只想为我的一个方案(例如 http://localhost:port/Controller/MyMethod/{ViewType}
)执行此路由实施,我尝试了 this 但它似乎没有做任何事情:
routes.MapRoute(
"MyRoute",
"MyController/Index/{MyEnum}",
new { controller = "MyController", action = "Pending" }
);
你确实可以。不要更改默认路由 "{controller}/{action}/{id}"
,而是在默认路由之前添加一个。这个新的需要相当具体:
routes.MapRoute(
"EnumRoute",
"Controller/MyMethod/{myEnum}",
new { controller = "Controller", action = "MyMethod", myEnum = UrlParameter.Optional }
);
基本上说的就是"when you see request to literally Controller/MyMethod/whatever, use this controller and that method and pass whatever as parameter of the request"。请注意,实际控制人不一定必须是 url 中所说的路线,尽管坚持这一点是个好主意。
/Controller/MyMethod/All
确实有效。问题在于默认路由,它将 All
视为 id
路由参数,这与您的操作用作参数的内容不一致。如果您的动作签名是:
public ActionResult MyMethod(MyEnum id = MyEnum.Pending)
因为它将 All
绑定到正确的东西。
您可以为此use-case添加另一条路线,但您需要注意不要只是创建另一条"default"路线, 它将接管。换句话说,您必须修复 URL:
的一部分routes.MapRoute(
"MyCustomRoute",
"Controller/{action}/{myEnum}",
new { controller = "Controller", action = "MyMethod", myEnum = MyEnum.Pending }
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
然后,仅通过路由的 /Controller/
前缀,它将使用您的自定义路由,并为 myEnum
参数填写 All
,而不是点击默认路由并尝试填写 id
.
但是,请注意,当使用枚举作为路由参数时,它们必须完全匹配。因此,虽然 /Controller/MyMethod/All
有效,但 /Controller/MyMethod/all
无效。要解决这个问题,您必须创建一个自定义模型活页夹。我进行了快速搜索,找到了以下 article,可能会在这方面对您有所帮助。