I can't get @Html to work with MVC 3. To render a formatted string, use DisplayFor.

asp.net-mvc c# data-annotations entity-framework linq-to-entities

Question

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!

1
12
9/6/2011 5:52:06 AM

Accepted Answer

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?

16
9/5/2011 8:57:59 PM

Popular Answer

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?



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow