我有一个看起来像这样的ReportController:
public IActionResult ReportDetails(int? reportId){
....
}
和
public IActionResult ReportDetails(int? reportId, bool ? approved) {
....
}
我尝试做一些路由,但失败了。用Startup.cs编写的实际代码:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "ReportDetailsValidation",
template: "descriptionValidation",
defaults: new { controller = "Report", action = "ReportDetails", reportId ="{reportId}", approved = "{approved}" }
);
routes.MapRoute(
name: "ReportDetails",
template: "description",
defaults: new { controller = "Report", action = "ReportDetails"}
);
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
正如我所见,我需要匹配以下网址:
第一个和第一个 / Report / ReportDetails?reportId = 7
/ Report / ReportDetails?reportId = 7& approved = True for second
答案 0 :(得分:0)
您可以按照此link了解路由
[HttpGet("Report/ReportDetails/{reportId}")]
[HttpGet("Report/ReportDetails/{reportId}/{approved}")]
public IActionResult ReportDetails(int? reportId, bool? approved) {
....
}
答案 1 :(得分:0)
您可以创建ActionMethodSelectorAttribute
。在您的控制器中,您可以将属性添加到两个方法中,以便将正确的方法与URL匹配。
例如,您可以制作一个ParameterExistsAttribute
来确定该方法是否合适,然后使用
[ParameterExists('approved', false)]
public IActionResult ReportDetails(int? reportId){
....
}
[ParameterExists('approved', true)]
public IActionResult ReportDetails(int? reportId, bool ? approved) {
....
}
关于如何实现这种属性的难题仍然是读者的练习。 (这并不困难。)
这里的示例是一个根据参数值选择API调用的属性。
public class FormPostFilterAttribute : ActionMethodSelectorAttribute
{
private readonly string _elementId;
private readonly string _requiredValue;
public FormPostFilterAttribute(string elementId, string requiredValue)
{
_elementId = elementId;
_requiredValue = requiredValue;
}
public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
if (string.IsNullOrEmpty(controllerContext.HttpContext.Request.Form[_elementId]))
{
return false;
}
return (controllerContext.HttpContext.Request.Form[_elementId] == _requiredValue);
}
}
答案 2 :(得分:0)
你不能这样做,就像有两个方法具有相同名称和不同参数一样,因为你应该得到 AmbiguousActionException 。
ASP核心操作选择器在选择操作期间不关心Action的参数。因此,您无法对应一个路径模板执行2个操作。唯一的解决方法是使用动作约束(如HttpGet和HttpPost)。 你可以check it yourself on GitHub。 (参见 SelectBestCandidate 方法)
理论上,如果参数很重要,基于参数的动作之间的选择逻辑应该在 SelectBestActions 方法中,但它会忽略参数。
在你的情况下,好的选择似乎只有一个方法:
public IActionResult ReportDetails(int? reportId, bool? approved) {
....
}
然后检查被批准是否为NULL( / Report / ReportDetails?reportId = 7 ),然后实现第一个逻辑,否则( / Report / ReportDetails?reportId = 7& approved = True )实现第二个逻辑。如果逻辑包含许多行,您可以用新方法提取它们并调用它。
public IActionResult ReportDetails(int? reportId, bool? approved) {
if (approved != null)
{
//implement logic for 2nd case(approved=True)
}
//implement logic for 1st case (just reportId=7)
}
答案 3 :(得分:0)
您可以使用RouteAttribute
[Route("ReportDetails/{reportId}")]
public IActionResult ReportDetails(int? reportId){
....
[Route("ReportDetails/{reportId}/{approved}")]
public IActionResult ReportDetails(int? reportId, bool ? approved) {
....
您的网址将是;
/ Report / ReportDetails / 7表示第一个和
/ Report / ReportDetails / 7 / True for second
这适用于默认的startup.cs
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});