ルートパラメータにカスタムルーティング制約を追加すると、リンクの構築に使用する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を作成します。
@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がルートパラメーターを認識しない理由について何か考えはありますか?