Asp – How to override the string representation the HTML helper methods use for a model’s properties

asp.net-mvc

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.

Best Answer

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:

<input type="text" name="UnitPrice" value="$1.23" />

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.

Related Topic