views:

78

answers:

3

So let's say I have a view that access a date:

<%= Html.TextBoxFor(model => Model.Birthday) %>

How do I have my view dictate how that date is formatted? I'd like to use common formatting options, and it's important that this is 2-way (both for display and data-entry).

+2  A: 

Use a specific ViewModel class that has a string in the format you want for the birthday and use that to display in the textbox. When you post the form, if you are using default binding for the domain object itself, it should parse the string for you. If you are using a ViewModel, you'll have to parse it upon posting the form.

Lance Harper
This seems wrong for this to go in anything but the View. The entire point of a view in MVC is to handle these sorts of manipulations. Is ASP.NET MVC v2 really that short-sighted? (Of course, no offense to you despite my textual tone here - I'm just shocked that this is not a trivial thing to do!)
Jaxidian
I see your point, but I think that a ViewModel class is supposed to contain specific View related logic and translate the business concept of the date to the string representation for display. The view itself is just the HTML and displays the string representations.
Lance Harper
Don't get me wrong, I have nothing against a ViewModel and its existence in MVC at the View-level, but that should be for more complex things than simply formatting a date.
Jaxidian
I'm flagging this as an answer although I'm very unhappy with this. I went out and wrote a FormattedTextBoxFor extension and I have it working perfectly except for cleaning up the value when posting, but that's for another question. Will post it on CodePlex as soon as I can figure out how to clean up the post data.
Jaxidian
+2  A: 

In your model, you could use System.ComponentModel.DataAnnotations metadata to specify the format you want the property in. e.g.

[DisplayFormat(DataFormatString="{0:MM/dd/yyyy}")]
public DateTime Birthday { get; set; }

Then, in your view, use:
<%= Html.EditorFor(model => model.Birthday) %>

Unfortunately, the regular HTML Helpers don't respect the metadata, so you have to use Html.EditorFor.

Malevolence
Useful DataAnnotation tag that I was not aware of, however, I refuse to put this into my Model because then I'm doing MVC wrong. Into my ViewModel, perhaps, but I still don't like this solution as this absolutely belongs in the View and nowhere else. +1 for the info, though.
Jaxidian
A: 

I was kind of surprised to see that you can't just throw a format string in Html.EditorFor(). I've sinced starting using EditorTemplates.

Create a directory structure in your solution.

Views > Shared > EditorTemplates

Add a new MVC 2 User Control in the EditorTemplates folder and name it DateTime.ascx. Html.EditorFor(DateTime) will now use this user control for display.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<DateTime?>" %>
<%= Html.TextBox(string.Empty, (Model.HasValue ? Model.Value.ToShortDateString() : string.Empty)) %>
CannibalCorpse
And this works for the binding in both directions? i.e. when you post, the value you enter here is sent back into the model?
Jaxidian
Yeah it does. So, say you make one for Decimal and format your textbox to currency. On your post method, you'll have to strip out the dollar sign or ModelState.IsValid will return false.
CannibalCorpse