Asp.net mvc 3 Url.Action MVC3在构建链接时未识别路由参数
将自定义路由约束添加到我的路由参数时,我发现它正在破坏我用来构建链接的Url.Action方法。如果路由约束只是一个正则表达式,那么Url.Action方法将继续识别该参数,但是如果它是我定义的自定义约束,则Url.Action方法将我的参数作为请求参数 以下是我的路线定义:Asp.net mvc 3 Url.Action MVC3在构建链接时未识别路由参数,asp.net-mvc-3,asp.net-mvc-routing,url.action,Asp.net Mvc 3,Asp.net Mvc Routing,Url.action,将自定义路由约束添加到我的路由参数时,我发现它正在破坏我用来构建链接的Url.Action方法。如果路由约束只是一个正则表达式,那么Url.Action方法将继续识别该参数,但是如果它是我定义的自定义约束,则Url.Action方法将我的参数作为请求参数 以下是我的路线定义: routes.MapRoute( "Event", "Events/{strDate}", new { controller = "Events",
routes.MapRoute(
"Event",
"Events/{strDate}",
new { controller = "Events", action = "Index", strDate = DateTime.Today.ToString("yyyy-MM-dd") },
new { strDate = new IsValidDateConstraint() },
new[] { "MyProject.Controllers" }
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new[] { "MyProject.Controllers" }
);
IsValidDateConstraint类继承自IRouteConstraint,如果strDate参数正确解析为DateTime对象,则返回true或false:
public class IsValidDateConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if (routeDirection == RouteDirection.IncomingRequest)
{
DateTime dt = new DateTime();
if (DateTime.TryParse(values["strDate"].ToString(), out dt))
return true;
}
return false;
}
}
使用Url.Action方法生成Url的:
@Url.Action("Index", "Events", new { strDate = ViewBag.CurrentDate.AddDays(1).ToString("yyyy-MM-dd") })
结果链接为:/Events?strDate=2012-08-15
如果我键入/Events/2012-08-15,所有内容都正确路由,那就是Url.Action方法没有识别出strDate是仅在我应用自定义路由约束时在路由中定义的参数。如果我注释掉自定义路由约束,那么Url.Action方法将正确映射Url
当我定义了自定义路由约束时,你知道为什么Url.Action不能识别我的路由参数吗?你没有展示你的
IsValidDateConstraint
的样子,但请确保你正在对yyyy-MM-dd
格式进行区域性不变解析:
public class IsValidDateConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
DateTime date;
return DateTime.TryParseExact(
values[parameterName] as string,
"yyyy-MM-dd",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out date
);
}
}
还要确保将此管线放置在默认管线之前:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Event",
"Events/{strDate}",
new { controller = "Events", action = "Index", strDate = DateTime.Today.ToString("yyyy-MM-dd") },
new { strDate = new IsValidDateConstraint() },
new[] { "MyProject.Controllers" }
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
另外,DateTime.Parse(ViewBag.CurrentDate.ToString())
看起来有点像WTFkish代码。如果ViewBag.CurrentDate
已经是日期时间,您可以直接写入:
@Url.Action(
"Index",
"Events",
new {
strDate = ViewBag.CurrentDate.AddDays(1).ToString("yyyy-MM-dd")
}
)
显然,更好的解决方案是使用视图模型:
@Url.Action(
"Index",
"Events",
new {
strDate = Model.CurrentDate.AddDays(1).ToString("yyyy-MM-dd")
}
)
更新: 既然您已经展示了代码,那么问题来自于您在约束中设置的if条件:
if (routeDirection == RouteDirection.IncomingRequest)
使用
Url.Action
helper时,此条件永远不会满足。仅当解析传入url时。因此,如果希望此约束与url帮助程序一起使用,则必须将其删除。您尚未显示您的isValidDataConstraint
的外观,但请确保您正在对yyyy-MM-dd
格式执行区域性不变解析:
public class IsValidDateConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
DateTime date;
return DateTime.TryParseExact(
values[parameterName] as string,
"yyyy-MM-dd",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out date
);
}
}
还要确保将此管线放置在默认管线之前:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Event",
"Events/{strDate}",
new { controller = "Events", action = "Index", strDate = DateTime.Today.ToString("yyyy-MM-dd") },
new { strDate = new IsValidDateConstraint() },
new[] { "MyProject.Controllers" }
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
另外,DateTime.Parse(ViewBag.CurrentDate.ToString())
看起来有点像WTFkish代码。如果ViewBag.CurrentDate
已经是日期时间,您可以直接写入:
@Url.Action(
"Index",
"Events",
new {
strDate = ViewBag.CurrentDate.AddDays(1).ToString("yyyy-MM-dd")
}
)
显然,更好的解决方案是使用视图模型:
@Url.Action(
"Index",
"Events",
new {
strDate = Model.CurrentDate.AddDays(1).ToString("yyyy-MM-dd")
}
)
更新: 既然您已经展示了代码,那么问题来自于您在约束中设置的if条件:
if (routeDirection == RouteDirection.IncomingRequest)
使用
Url.Action
helper时,此条件永远不会满足。仅当解析传入url时。因此,如果希望此约束与url帮助程序一起使用,则必须删除它。我已更新了我的帖子,以包含我使用的所有代码。请记住,我设置的每个路由约束都会出现此问题,而不仅仅是检查有效日期时间字符串的约束。至于ViewBag,您是对的,我不知道为什么要在那里进行双重解析,但由于这是我需要的唯一变量,我发现不创建ViewModel更容易。这些信息非常翔实准确,但问题仍然存在。还有其他想法吗?在您的约束中,您使用的是if(routeddirection==routeddirection.IncomingRequest)
。这就是你的代码不起作用的原因。当由Url.Action helper计算时,它总是返回false,因为这不是传入请求。请看我在答案中显示的代码。我的约束中没有这样的if
条件。我已经更新了我的答案,在最后包含了这些信息。这很有意义,我感谢你的帮助。非常感谢。我已经更新了我的帖子,包含了我使用的所有代码。请记住,我设置的每个路由约束都会出现此问题,而不仅仅是检查有效日期时间字符串的约束。至于ViewBag,您是对的,我不知道为什么要在那里进行双重解析,但由于这是我需要的唯一变量,我发现不创建ViewModel更容易。这些信息非常翔实准确,但问题仍然存在。还有其他想法吗?在您的约束中,您使用的是if(routeddirection==routeddirection.IncomingRequest)
。这就是你的代码不起作用的原因。当由Url.Action helper计算时,它总是返回false,因为这不是传入请求。请看我在答案中显示的代码。我的约束中没有这样的if
条件。我已经更新了我的答案,在最后包含了这些信息。这很有意义,我感谢你的帮助。非常感谢。