Monday, July 1, 2013

What's rawer than Razor's raw?

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

@{
    System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("fr-FR");
    decimal d = 1234567.89M;
}


@d

<hr />

@Html.Raw(d)



The output is:

1234567,89 
1234567,89

I wanted to return these though:
1234567,89
1234567.89


Yeah I know, raw != English-centric, the world doesn't revolve around English culture. However, the programming language's raw(or culture if you may) is English-centric, i.e., we write one milllion and two hundred thirty four thousand five hundred sixty seven pesos and eighty nine centavos as 1234567.89 not 1234567,89

I want to use 1234567.89 even I'm in other culture. What's the use of that whimsical need? It's easier to bridge server-side values to javascript when the programming language format is preserved properly.

This view...

@{
    System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("fr-FR");
    decimal d = 1234567.8912M;
}

<script>    
    var x = @d;
    alert(x);    
</script>

...is materialized to html as the following, an invalid syntax, hence the alert will not pop-up:

<script>    
    var x = 1234567,89;
    alert(x);    
</script>


Any suggestion? I'll post this stackoverflow and will keep you posted when an answer come up


UPDATE: Feb 19, 2014


Some answers are just coming up when there's a damning need for a solution to a problem. A colleague has a problem on his Razor view. His problem is similar to above, he's passing a Model(with numeric values) from controller to view, and in turn his view is passing the model's numeric values to a JavaScript control, this is his razor view:


<script>
var c = chart.setup({ LowestScore : @Model.LowestScore, HighestScore : @Model.HighestScore });
</script>


However this is the HTML output of Razor view:
<script>
var c = chart.setup({ LowestScore : 12345,67 , HighestScore : 56789,12 });
</script>


Spot the error? It's not a valid JavaScript, the cents gets separated from the values. The problem stems from the razor being locale-aware, so if you set the language to French, the fraction will get emitted with comma separator. To fix the problem, we just serialize the values right there on View. Why on view and not on controller? If we do it on controller we are compelled to introduce another property on the model for the JSON string of the values we wanted to pass from the model, or worse yet we have to marshal it to ViewBag or ViewData from the controller. With that in mind, this is the best way to tackle the problem, serialize the values in View:

<script>
    @{
        string j = Newtonsoft.Json.JsonConvert.SerializeObject(
            new 
            { 
                LowestScore = Model.LowestScore,
                HighestScore = Model.HighestScore,                 
            });
    }

    var jsonObject = @Html.Raw(j);
    var c = chart.setup(jsonObject);
</script>



HTML generated:
<script>
    var jsonObject = {"LowestScore":12345.67,"HighestScore":56789.12};
    var c = chart.setup(jsonObject);
</script>



I hope I'm wrong with my approach above, if there's a shorter way to do it in Razor, i.e. its localization can be turned off programatically, I'll be more than glad to know.



Happy Coding! ツ

No comments:

Post a Comment