I have the following route mapped in my test MVC3 project -
routes.MapRoute(
"TestRoute",
"test/{DateFrom}/{DateTo}",
new { controller = "Home", action = "TestRoute" }
);
I am then building a link in the view as follows -
@Html.ActionLink("Test Link", "TestRoute", new
{
DateFrom = new DateTime(2006, 02, 16),
DateTo = new DateTime(2008, 04, 22)
})
Which when rendered, outputs this URL -
/test/02/16/2006%2000%3a00%3a00/04/22/2008%2000%3a00%3a00
As you can see, the framework has called ToString()
on the DateTime
parameters and then encoded the result.
I would like to format the DateTime route parameters so they are output as "yyyy-MM-dd".
Obviously I can specify the format when building the Action Link like so -
@Html.ActionLink("Test Link", "TestRoute", new
{
DateFrom = new DateTime(2006, 02, 16).ToString("yyyy-MM-dd"),
DateTo = new DateTime(2008, 04, 22).ToString("yyyy-MM-dd")
})
However we know this is messy, cumbersome and not DRY.
I have tried using [DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}")]
attribute on the properties in the model hoping this was the answer, however it seems these are only respected when building editor forms.
FYI, if I manually type the DateTime
parameters in the URL in my browser (e.g. /test/2006-02-16/2008-04-22) the parameters are correctly parsed, so it's just a case of getting them formatted how I want.
You could write a custom helper to handle links that have dates:
namespace System.Web.Mvc {
public static class LinkExtensions {
public static MvcHtmlString DateLink(this HtmlHelper htmlHelper, string linkText, string actionName) {
return DateLink(htmlHelper, linkText, actionName, new RouteValueDictionary(), null);
}
public static MvcHtmlString DateLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues) {
return DateLink(htmlHelper, linkText, actionName, new RouteValueDictionary(routeValues), new RouteValueDictionary());
}
public static MvcHtmlString DateLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues, object htmlAttributes) {
return DateLink(htmlHelper, linkText, actionName, new RouteValueDictionary(routeValues), HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static MvcHtmlString DateLink(this HtmlHelper htmlHelper, string linkText, string actionName, RouteValueDictionary routeValues) {
return DateLink(htmlHelper, linkText, actionName, routeValues, new RouteValueDictionary());
}
public static MvcHtmlString DateLink(this HtmlHelper htmlHelper, string linkText, string actionName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
if (String.IsNullOrEmpty(linkText)) {
throw new ArgumentException("linkText");
}
//check additional parameters
List<string> keys = new List<string>(routeValues.Keys);
foreach (string key in keys) {
if (routeValues[key].GetType() == typeof(DateTime))
routeValues[key] = ((DateTime)routeValues[key]).ToString("yyyy-MM-dd");
}
return MvcHtmlString.Create(HtmlHelper.GenerateLink(htmlHelper.ViewContext.RequestContext,
htmlHelper.RouteCollection, linkText, null, actionName, (string)routeValues["controller"], routeValues, htmlAttributes));
}
}
And then you could use it like so:
@Html.DateLink("TestLink", "Details", new { starttime = new DateTime(2011, 1, 1), endtime = new DateTime(2012, 1, 1)})
Which produces the following URL:
http://localhost/MyController/Details/2011-01-01/2012-01-01
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With