1

I have page that will show some currency data. I want to format the data with currency format but only using Display Template.

I have the following code:

 @foreach (var item in Model.Data)
{
    <tr class="@(item.Group%2==0? "odd-colore": "even-colore")">
    <td>@Html.DisplayFor(modelItem => item.Name)</td>
    <td>@Html.DisplayFor(modelItem => item.Amount1)</td>      
    <td>@Html.DisplayFor(modelItem => item.LName)</td>
    <td>@Html.DisplayFor(modelItem => item.Amount2)</td>
    <td>@Html.DisplayFor(modelItem => item.Amount3)</td>

    </tr>
}   

I have created a DisplayTemplate String.cshtml, since my datatype is string:

@model string

@{ 
    IFormatProvider formatProvider = new System.Globalization.CultureInfo("en-US");
    <span class="currency">@Model.ToString("C",formatProvider)</span>
}

But when I run it, I'm getting the error:

No overload for method 'ToString' takes 2 arguments

How can I display positive amount as $1000.00 and negative amount as ($1000.00) either using DisplayTemplate or string.Format("{0:C}")

tereško
  • 58,060
  • 25
  • 98
  • 150
gene
  • 2,098
  • 7
  • 40
  • 98

1 Answers1

0

The problem you're having is because you're trying to convert a string to a currency. From MSDN:

The Currency ("C") Format Specifier

The "C" (or currency) format specifier converts a number to a string that represents a currency amount.

The .ToString(string format, IFormatProvider formatProvider) overload you're trying to use only exists for numeric types, which is why it's not compiling.

As an example to demonstrate this:

public class TestModel
{
    public decimal Amount { get; set; }
    public string StringAmount { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var model = new TestModel
        {
            Amount = 1.99M,
            StringAmount = "1.99"
        };

        IFormatProvider formatProvider = new CultureInfo("en-US");

        // Prints $1.99
        Console.WriteLine(model.Amount.ToString("C", formatProvider));

        // Prints 1.99
        Console.WriteLine(string.Format(formatProvider, "{0:C}", model.StringAmount));
    }
}

So you have a couple of choices:

  1. Convert your data to a numeric type in the template, and then format it.
  2. Store your data as a numeric type to begin with.

I believe 2 is the better option, because you're wanting to work with numeric data, so storing it as a string only adds complexity when it comes to calculating and formatting (as you can see here), as you're always going to have to perform conversions first.

Community
  • 1
  • 1
John H
  • 14,422
  • 4
  • 41
  • 74
  • I cannot store data as a numeric unfortunately, because sometimes I may get am empty string as an Amount. My property is a string type to get mapped to the xml property returned from the database that can contain an empty string – gene Mar 14 '17 at 20:00
  • I cannot store data as a numeric unfortunately, because sometimes I may get am empty string as an Amount. My property is a string type to get mapped to the xml property returned from the database that can contain an empty string. So, basically, I would need to use `@model string`. But, since it is inside of the `DIsplayTemplate`, I'm not sure how to use it for a specific columns in `@Html.DisplayFor(modelItem => item.Data.ProductCost, "Currency"` format. My Display Template is called "Currency" – gene Mar 14 '17 at 20:17
  • @gene Sorry for not responding sooner. There is an overload of `Html.DisplayFor` that does take a template name as a second parameter, so your example of `@Html.DisplayFor(modelItem => item.Data.ProductCost, "Currency")` should actually work. If it's not, it will be because it's not able to locate the template. You can also use the [UIHint attribute](https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.uihintattribute.uihint(v=vs.110).aspx) on your model's properties. – John H Mar 16 '17 at 22:20