Reputation: 1255
I'm hoping this is quite a simple one, although after lots of Googling, I've not been able to work it out.
I'm working on a shopping cart site with MVC 3, and using code-first Entity Framework. The model I'm sending over is a list of Product objects, and each of those objects includes this property:
[Required(ErrorMessage = "This is a required field.")]
[DataType(DataType.Currency)]
[Range(1.00, 500.00, ErrorMessage = "Products can not be free.")]
[DisplayFormat(DataFormatString = "{0:C}")]
[DisplayName("Price")]
public double Price { get; set; }
I was hoping that the DisplayFormat attribute would cause the following line in the view to format the value as a currency (item is the product object in the loop):
@Html.DisplayFor(modelItem => item.Price)
But this doesn't apply the formatting at all. So far the only way I've been able to get it to work is to use this instead:
@String.Format("{0:C}", item.Price)
But if it's possible, I'd rather use @Html.DisplayFor as it's designed to handle things like nulls. I know it's going to be 0 or more. In fact with the validation it'll always be some amount - but I want to make sure there isn't a more correct way of doing this before I carry on.
Any information on this would be most appreciated!
UPDATE
Darin answered and pointed out that it does work, which caused me to go back over what I was actually sending over to the view. I realised that although I have a class called ProductModel, which has the DisplayFormat attribute, I was actually returning another model which contains a list of products. This is called ProductListModel and I realised that it returned a list of the Product data class - not the ProductModel class!
So in the end it was actually very simple. Just wish I hadn't wasted half an evening on it. Thanks for inspiring me to go back and check properly, Darin!
Upvotes: 12
Views: 20339
Reputation: 93434
One option is to create a Currency.cshtml
DisplayTemplate
and remove the DisplayFormat
attribute. Then in your Currency.cshtml
you would format it however you like.
As part of the templating process, DataType
is used to select a template.
However, as Darin says, this should work without doing this. Do you, by any chance already have a Currency.cshtml
file in your DisplayTemplates
that does not apply formatting?
Upvotes: 0
Reputation: 1038780
But this doesn't apply the formatting at all.
Oh, you gotta be doing something very wrong as the DisplayFormat attribute should work. For example:
Model:
public class MyViewModel
{
[Required(ErrorMessage = "This is a required field.")]
[DataType(DataType.Currency)]
[Range(1.00, 500.00, ErrorMessage = "Products can not be free.")]
[DisplayFormat(DataFormatString = "{0:C}")]
[DisplayName("Price")]
public double Price { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
Price = 0.56
};
return View(model);
}
}
View (~/Views/Home/Index.cshtml
):
@model MyViewModel
@Html.DisplayFor(x => x.Price)
When I run this application I get, as totally expected, $0.56
.
So what gives? How does your scenario differs than mine?
Upvotes: 16