在我的路由参数中添加自定义路由约束时,我发现它破坏了我用来构建链接的Url.Action方法。如果路径约束只是一个正则表达式,那么Url.Action方法将继续识别该参数,但是如果它是我定义的自定义约束,则Url.Action方法将我的参数作为请求参数。
这是我的路线定义:
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.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无法识别我的路径参数的任何想法?
答案 0 :(得分:4)
您尚未展示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
已经是DateTime,您可以直接写:
@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
助手时,永远不会满足此条件。仅在解析传入的URL时。因此,如果您希望此约束与url帮助程序一起使用,则必须将其删除。