Often you want to return data with your call to retrieve a web page/control from ASP.NET MVC so that it can be accessed via JavaScript as a ViewModel (using KnockoutJS or equivalent).
Typically, you make a server call to retrieve the web page using the standard ASP.NET controller action and then make a AJAX call to go retrieve the model to populate your JavaScript ViewModel.
Wouldn't it be nice if you could send back the model with the page request and avoid a separate AJAX call?
Using the ViewBag, a HTML Helper method and some JSON serialization formatters we can easily take a C# model and serialize it down with a page request to be actioned by JavaScript.
Start by pushing the data model onto the ViewBag.
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Name = "Donkey Kong";
return View();
}
Serialize the ViewBag into a namespaced/global JavaScript variable.
<!DOCTYPE html>
<html lang="en">
<head>
...
<script type="text/javascript">
window.viewBag = @Html.ToJson((object)ViewBag)
</script>
</head>
<body>
...
</body>
</html>
Here is the helper method to serialize the ViewBag to JSON. It even converts the C# PascalCasing to JavaScript camelCasing.
public static class HtmlHelpers
{
/// <summary>
/// Converts a viewbag object to Json
/// </summary>
/// <param name="viewBagObject">Object to make into Json</param>
/// <returns>Javascript object</returns>
public static IHtmlString ToJson(this HtmlHelper html, dynamic viewBagObject)
{
var json = JsonConvert.SerializeObject(
viewBagObject,
Formatting.Indented,
new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }
);
return html.Raw(json);
}
}
Now you can access the model data from your JavaScript.
var vm = window.viewBag;
alert(vm.name);
You'll need to NuGet the Newtonsoft.Json library.
Serialize, ViewModel, Knockout, JavaScript, ViewBag, Model, AJAX