有点噩梦,希望我只是愚蠢。
我有以下控制器操作:
<HttpGet()>
Function News() As ActionResult
End Function
<HttpGet()>
Function News(ByVal id As Integer) As ActionResult
End Function
我希望它是聪明的,如果我在网址中没有ID,则转到第一个,如果有,则转到第二个。
我收到以下错误:
当前关于控制器类型'MarketsController'的操作'新闻'请求在以下操作方法之间是不明确的: TradeChaseMVC.MarketsController类型的System.Web.Mvc.ActionResult News() TradeChaseMVC.MarketsController类型的System.Web.Mvc.ActionResult News(Int32)
所以,我想如果我明确创建了没有id参数可选的路由,就像这样:
routes.MapRoute( _
"Default2", _
"{controller}/{action}/{id}",
New With {.controller = "Home", .action = "Index"},
New With {.action = "^[a-zA-Z_]+$", .id = "\d{1,8}|"}
)
routes.MapRoute( _
"Default", _
"{controller}/{action}",
New With {.controller = "Home", .action = "Index"},
New With {.action = "^[a-zA-Z_]+$"}
)
它会起作用,但它没有同样的错误。
现在我知道简单的解决方案是调用我的方法不同的东西,但我不想这样做。
我还在考虑创建一个属性来为ID方法添加前缀,检查ID是否存在,以及它是否不允许该方法,但我也无法使其工作。
任何帮助将不胜感激。 卡尔
答案 0 :(得分:2)
您可以使用UrlParameter.Optional和可以为空的ID来解决此问题:
routes.MapRoute( _
"Default2", _
"{controller}/{action}/{id}",
New With {.controller = "Home", .action = "Index", id = UrlParameter.Optional},
New With {.action = "^[a-zA-Z_]+$", .id = "\d{1,8}|"}
)
Function News(ByVal id As Integer?) As ActionResult
if id.HasValue then
...
else
...
end if
End Function
答案 1 :(得分:1)
问题仍然是,一旦它识别了要调用的动作的名称,MVC动作调用者就无法在两种方法之间进行选择,因为它不会分析请求以查看哪些参数可能< / em>被绑定。
在选择方法之前,不会发生参数绑定阶段;所以你必须给它们不同的名字 - 或者你可以使id
参数成为可以为空的整数(并保持可选的id route参数为默认值),如果它是null,则简单地链接到另一个重载。
如果你这样做,一定要用NonActionAttribute
来装饰非参数重载,这样动作调用者就不会感到困惑,或者确实把它变成私有/保护。
根据我们的评论进行更新 - 如果重命名您的操作方法,则无需返回REST标准 - 您只需使您的路线更具体(我提前道歉 - VB.Net甚至不是我的第二语言! ):
<HttpGet()>
<ActionName("AllNews")>
Function News() As ActionResult
End Function
<HttpGet()>
Function News(ByVal id As Integer) As ActionResult
End Function
'-- route for single news item with constraint
routes.MapRoute(
"News",
"Markets/News/{id}",
New With { .controller = "Markets", .action = "News" },
New With { .id = "\d{1,8}" });
'-- route for the all news action method
routes.MapRoute(
"AllNews",
"Markets/News",
New With { .controller = "Markets", .action = "AllNews" });
现在你必须使用明确的路由来定位两个动作方法,但是在相同的RESTful uri方案下。
所有我的MVC REST服务都倾向于使用更多这样的显式路由,原因与您尝试解决的原因完全相同。