Here's a Money display template:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<decimal?>" %>
<%= Html.TextBox( string.Empty, (Model.HasValue ? Model.Value.ToString("C") : string.Empty), new { @class = "money" } ) %>
and editor template
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<decimal?>" %>
<%= Html.TextBox( string.Empty, (Model.HasValue ? Model.Value.ToString("0.00") : string.Empty), new { @class = "money" } ) %>
I'd suggest defining the CSS class money, but you could replace that with the other classes if you want. Name them both Money.ascx and put them in Views\Shared\DisplayTemplates and Views\Shared\EditorTemplates, respectively.
Used as
<%= Html.DisplayFor( x => x.Price, "Money" ) %>
<%= Html.EditorFor( x => x.Price, "Money" ) %>
EDIT: the other thing you can do if you want to have different editor/display formats (as I do) is extend the DataAnnotationsModelMetadataProvider, implement a new EditFormatAttribute that provides the format when in edit mode (this overrides the DataAnnotations setting), the supply both a display format and edit format via the two attributes.
public class ExtendedDataAnnotationsMetadataProvider : DataAnnotationsModelMetadataProvider
{
private HttpContextBase Context { get; set; }
public ExtendedDataAnnotationsMetadataProvider() : this( null ) { }
public ExtendedDataAnnotationsMetadataProvider( HttpContextBase httpContext )
{
this.Context = httpContext ?? new HttpContextWrapper( HttpContext.Current );
}
protected override ModelMetadata CreateMetadata( IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName )
{
List<Attribute> attributeList = new List<Attribute>( attributes );
var metadata = base.CreateMetadata( attributes, containerType, modelAccessor, modelType, propertyName );
EditFormatAttribute editFormatAttribute = attributeList.OfType<EditFormatAttribute>().FirstOrDefault();
if (editFormatAttribute != null)
{
metadata.EditFormatString = editFormatAttribute.EditFormatString;
}
// RequiredAdminAttribute requiredAdminAttribute = attributeList.OfType<RequiredAdminAttribute>().FirstOrDefault();
// if (requiredAdminAttribute != null)
// {
// metadata.IsRequired = this.Context.User == null || requiredAdminAttribute.RequiredForUser( this.Context.User );
// }
return metadata;
}
}
public class EditFormatAttribute : Attribute
{
public string EditFormatString { get; set; }
}
Then hook it up in Global.asax.cs in Application_Start()
ModelMetadataProviders.Current = new ExtendedDataAnnotationsMetadataProvider();
This allows you to configure your model properties like:
[DataType( DataType.Currency )]
[DisplayFormat( DataFormatString = "{0:C}", ApplyFormatInEditMode = false )]
[EditFormat( EditFormatString = "{0:0.00}" )]
public decimal? Amount { get; set; }
This allowed me to get rid of the templates I showed above and retain the ability to easily apply HTML attributes to the generated fields. I thought it might be more complex than necessary. I did it to support an additional attribute that supports conditional requirement based on who the user is or their group membership is (commented out in the sample).