views:

336

answers:

1

Hi,

I just came across a very interesting issue. If I use ViewData to pass a DateTime value to the view and then display it inside a textbox, even though I'm using String.Format in the exact same manner, I get different formatting results when using the Html.TextBox helper.

<%= Html.TextBox("datefilter", String.Format("{0:d}", ViewData["datefilter"]))%>
<input id="test" name="test" type="text" value="<%: String.Format("{0:d}", ViewData["datefilter"]) %>" />

The above code renders the following html:

<input id="datefilter" name="datefilter" type="text" value="2010-06-18" />
<input id="test" name="test" type="text" value="18/06/2010" />

Notice how the fist line that uses the Html helper produces the date format in one way while the second one produces a very different output. Any ideas why?

Note: I'm currently in Brazil, so the standard short date format here is dd/MM/yyyy.

+3  A: 

The reason this happens is because the TextBox helper uses the value stored inside ViewData["datefilter"] because its name is datefilter and completely ignores the second argument you are passing which is supposed to format the date. Try changing the name of the textbox.

A better solution is to use editor templates and strongly typed views instead of ViewData. Here's an example.

Model:

public class MyModel
{
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", 
                   ApplyFormatInEditMode = true)]
    public DateTime Date { get; set; }
}

Controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MyModel
        {
            Date = DateTime.Now
        };
        return View(model);
    }
}

View:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<SomeNs.Models.MyModel>" %>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <%: Html.EditorFor(x => x.Date) %>
</asp:Content>
Darin Dimitrov
+1 Have a look at the last three paragraphs, it clarifies Darin's answer a bit more. http://weblogs.asp.net/jeff/archive/2009/08/18/under-the-covers-of-html-helpers-in-asp-net-mvc.aspx. The date should still be evaluated using the current culture, but its not. Why?
Ahmad
I see now what I did. Not only the ViewData had a key with the "datefilter" name, but also the name of the parameter for the route. So even after completly removing the ViewData, still the Html.TextBox("datefilter") was pulling it from the ModelState or somewhere. I just don't know why not being formatted according to current culture like Ahmad said. But I think now I understood a little better how these helpers should actually be used, thanks to you guys. And also, thanks for this great example Daring, it may seem trivial, but it's actually a lot nicer than using ViewData. ;)
Marcio Gabe