tags:

views:

715

answers:

1

The html helper methods check the ViewDataDictionary for a value. The value can either be in the dictionary or in the Model, as a property. To extract the value, an internal sealed class named the ViewDataEvaluator uses PropertyDescriptor to get the value. Then, Convert.ToString() is called to convert the object returned to a string.

Desired code in Controller action

The controller action should only populate the Model, not format it (formatting the model is global).

Desired code in View

The view can render a HTML textbox and extract the string representation of the property with this line of code:

<%=Html.TextBox(“Date”) %>
<%=Html.TextBox(“Time”) %>
<%=Html.TextBox(“UnitPrice”) %>

Binding Model's Property to HtmlHelper.TextBox()

For the textbox’s value, the UnitPrice property’s value from the model instance is converted to a string. I need to override this behavior with my own conversion to a string, which is per property – not per type. For example, I need a different string representation of a decimal for UnitPrice and another string representation of a decimal for UnitQuantity.

For example, I need to format the UnitPrice's decimal precision based on the market.

string decimalPlaces = ViewData.Model.Precision.ToString ();
<%=Html.TextBox(“UnitPrice”, ViewData.Model.TypeName.UnitPrice.ToString("N" + decimalPlaces)) %>

2-way databinding please

Just like the IModelBinder is the Parse for each property of the model, I need a Format for each property, kinda like Windows Forms binding, but based on the model instead of the control. This would enable the model to round-trip and have proper formatting. I would prefer a design where I could override the default formatting. In addition, my model is in a separate assembly, so attributed properties specifying a formatter are not an option.

Please note I need property specific formatting for a model, not type specific formatting.

+3  A: 

There's no way to specify a format with the helpers themselves. The approach you've taken will work. Another approach is to add the value pre-formatted into the ModelState.

EDIT: Are you sure you even want to format a text input with the currency? For example, what you would see in the input is:

When you post that back to the server, we won't understand it. Instead, I'd put the currency symbol outside of the text input. For example:

$<%= Html.TextBox("UnitPrice") %>

I'm sure there's an easy method to render "$" without hard-coding it so it's localizable, but I don't know what it is offhand.

EDIT AGAIN A comment from a developer on my team:

Well, to be fair, this isn’t that bad. Often when you format a number or a date it’s still understandable coming back in. For example, padding a number (like a ZIP code) to 5 digits, padding a decimal to the hundredths, formatting a date to be yyyy-mm-dd, etc. will come in just fine. Adding extra characters like currency symbols will break, but normally input fields don’t take or display currency symbols anyway – it’s implied.

Haacked
I'm going to call a static helper to pre-format the Model into ModelState on ever action that loads the model. As you say, this will work for now.
George Tsiokos
Also, there are many cases where you need to specify a specific format/parse - for example, a yy-mm-dd will not parse correctly: you need to call DateTime.ParseExact(...) on Parse, and DateTime.ToString(...) on Format
George Tsiokos