I think you are attacking it from the wrong angle by trying to encode all posted data.
Note that a "<
" could also come from other outside sources, like a database field, a configuration, a file, a feed and so on.
Furthermore, "<
" is not inherently dangerous. It's only dangerous in a specific context: when writing strings that haven't been encoded to HTML output (because of XSS).
In other contexts different sub-strings are dangerous, for example, if you write an user-provided URL into a link, the sub-string "javascript:
" may be dangerous. The single quote character on the other hand is dangerous when interpolating strings in SQL queries, but perfectly safe if it is a part of a name submitted from a form or read from a database field.
The bottom line is: you can't filter random input for dangerous characters, because any character may be dangerous under the right circumstances. You should encode at the point where some specific characters may become dangerous because they cross into a different sub-language where they have special meaning. When you write a string to HTML, you should encode characters that have special meaning in HTML, using Server.HtmlEncode. If you pass a string to a dynamic SQL statement, you should encode different characters (or better, let the framework do it for you by using prepared statements or the like)..
When you are sure you HTML-encode everywhere you pass strings to HTML, then set ValidateRequest="false"
in the <%@ Page ... %>
directive in your .aspx
file(s).
In .NET 4 you may need to do a little more. Sometimes it's necessary to also add <httpRuntime requestValidationMode="2.0" />
to web.config (reference).
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.
Best Answer
[EDIT] After looking at the source code, it appears that all you need to do is specify the value as null in the signature that takes a name, value, and htmlAttributes. If the value is null, it will attempt to use the value from the ViewData.