I was working in a way to convey a dataset coming from the database to Google Chart JavaScript framework, using C# and .NET Core MVC framework under the Razor Page.
The first step was easy, a trivial query to the database in order to get the data, but Google Chart has their special way to handle a dataset and to realize a simple conversion from POCO was not sufficient, then I wrote a converter:
private IEnumerable<Array> poco2GoogleChartDataset(IEnumerable<MyData> dataset)
{
List<Array> googleDataset = new List<Array>();
foreach (MyData data in dataset) {
Array arr = new object[] { data.Label, data.Value };
googleDataset.Add(arr);
}
return googleDataset.ToList();
}
The result of this conversion was serialized to JSON using the Newtonsoft.Json
assembly:
// Top of the class
using Newtonsoft.Json;
// Hidden for brevity
ReportJson = JsonConvert.SerializeObject(poco2GoogleChartDataset(myDataset));
On the other hand, in Razor Page, I need to pass this JSON object to a JavaScript variable. If you just pass the model value using a simple Razor syntax, it will not work because in the Razor Render process will pass the value through an HTML encoding. Like this:
// Razor Page
...
@section Scripts {
function drawChart() {
var jsonDataset = @Model.ReportJson;
...
}
...
}
jsonDataset result:
[[\"Label\", value]]
To bypass the HTML encoding wrap the model variable into the HtmlHelper directive with their Raw
method. This way:
// Razor Page
...
@section Scripts {
function drawChart() {
var jsonDataset = @Html.Raw(Model.ReportJson);
...
}
...
}
Now the value result will be a JSON object, ready to be used in Google Chart framework.
I suffered hours to achieve this comprehension, in part because I do not master Razor syntax, nor ASP.NET Core MVC, neither the C# 😂
That's it!
Top comments (3)
Be careful with Html.Raw. It can lead to XSS attacks.
For instance, what if somebody puts in the JSON data:
Will the script render? If so, you've just opened a security hole.
A better method is to read the data after the page loads with an AJAX call. This means your data is never loaded on the page so a script cannot be injected. With JQuery:
Another solution: use a hidden text input whose value =
@Model.ReportJson
. Then grab it as a string by JS.amazing.. I was doing some research about the JSON and C# and came across this tool jsonformatter.org/json-to-csharp. It's JSON to C# converter, I use it when I want to create some demo or tutorials.