ASP.NET MVC and Rendering both HTML and JavaScript
In the project I am currently working on, we are using JavaScript and jQuery in just about everything. One of the frustrations that I have been seeing is that I’ll render a view representing an object, but also want a JSON version of that object to manipulate. I am also quite anal when it comes to keeping my code clean and separating the concerns; I did not want to have JavaScript strewn throughout my HTML or vice versa.
I considered a couple of options. The first just involved making an AJAX call to the server and having it return a JsonResult. This is clean, but I did not want to effectively double my calls to the server.
I also considered extending the MVC framework and writing my own ActionResult class that returned both HTML and JSON. However, that also “felt” wrong; like I was short-circuiting the framework. I would have had to rely on JavaScript on the client side to parse the resulting object and place the HTML, not something I want to be doing with all of my views.
I let it sit on the backburner for a while, and then today came up with a pretty good solution. It’s not ideal, but it works well enough for me. I created a simple HtmlHelper extension that just dumps the JSON out into a variable:
using System.Web.Script.Serialization;
public static class JsonExtensions {
public static string Json(this HtmlHelper html, string variableName) {
return Json(html, variableName, html.ViewData.Model);
}
public static string Json(this HtmlHelper html, string variableName, object model) {
TagBuilder tag = new TagBuilder("script");
tag.Attributes.Add("type", "text/javascript");
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
tag.InnerHtml = "var " + variableName + " = " + jsonSerializer.Serialize(model) + ";";
return tag.ToString();
}
}
You call it from a page like so:
<%= Html.Json("foo") %>
<%= Html.Json("bar", Model.Something) %>
This is not an ideal solution, you are still technically putting JavaScript in the HTML. But, it does not make an extra call to the server, and the markup in the IDE is still very clean.
Another approach I considered was to have an Action that returned a JavaScriptResult that consisted of the same thing. You could then add a script tag like:
<script type="text/javascript" src="/javascript/MyObject/1000">
The catch though is that it would cause more overhead, especially if the app was designed in such a way that the retrievals are expensive (ours is).
I’m still ruminating on that perfect scenario, but for now I’ll be doing it this way.

Comments are closed.