JavaScript variable generation for ASP.NET MVC
31 Jan 2009RC1 of the ASP.NET MVC framework adds a new ActionResult, JavaScriptResult. This class takes a string and returns a response with the string with the required ContentType.
So now theres a built in (very simple) ActionResult for returning JavaScript what about generating the JavaScript string on the server to return?
One thing I do alot is to recreate service side enums on the client in JavaScript, so rather than checking values I can use names, which improves the readability of the javascript. However this requires both the server and the client to be kept in sync, which can be a pain.
To resolve this issue I’ve created a JavaScriptGenerator class which handles serialization of objects and Enum types as variables and generates the JavaScriptResult, as well as a helper method to take a controller name and action name and insert the required <script .. /> tag into the markup.
Note I’ve created my own JavaScriptHelper class, similar to HtmlHelper, that I extend with extension methods the are javascript specific. I’ve also got a bunch of other extension methods for registering variables in the html itself as well as adding the <script /> tag for a specified filename.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Mvc; using System.Web.Script.Serialization; namespace LukeSmith.Web.Mvc.JavaScript { public class JavaScriptGenerator { private StringBuilder builder; ////// Initializes a new instance of the class. /// public JavaScriptGenerator() { builder = new StringBuilder(); } ////// Generates a javascript variable from enum. /// /// The name to give the javascript variable. /// Type of the enum. /// /// Current instance of the . /// /// public JavaScriptGenerator GenerateVariableFromEnum(string name, Type enumType) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } if (enumType.IsEnum) { Array values = Enum.GetValues(enumType); JavaScriptSerializer serializer = new JavaScriptSerializer(); Dictionary dictionary =new Dictionary(); foreach (var value in values) { string enumName = Enum.GetName(enumType, value); dictionary.Add(enumName, value); } builder.Append(string.Format("var {0} = {1};", name, serializer.Serialize(dictionary))); } else { throw new InvalidOperationException("Cannot generate JavaScript code when enumType is not an Enum."); } return this; } ////// Generates a javascript variable from an object. /// /// The name to give the javascript variable. /// The value. /// /// Current instance of the . /// public JavaScriptGenerator GenerateVariableFromObject(string name, object value) { List converters = new List(); return this.GenerateVariableFromObject(name, value, converters); } ////// Generates a javascript variable from an object. /// /// The name to give the javascript variable. /// The value. /// The to use to convert the . /// /// Current instance of the . /// public JavaScriptGenerator GenerateVariableFromObject(string name, object value, JavaScriptConverter converter) { List converters = new List(); converters.Add(converter); return this.GenerateVariableFromObject(name, value, converters); } ////// Generates a javascript variable from an object. /// /// The name to give the javascript variable. /// The value. /// An of to use to convert the . /// /// Current instance of the . /// public JavaScriptGenerator GenerateVariableFromObject(string name, object value, IEnumerable converters) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } JavaScriptSerializer serializer = new JavaScriptSerializer(); serializer.RegisterConverters(converters); builder.Append(string.Format("var {0} = {1};", name, serializer.Serialize(value))); return this; } ////// Generates the . /// /// public JavaScriptResult Generate() { return new JavaScriptResult() { Script = this.ToString() }; } ////// Returns a that represents the current . /// /// /// A that represents the current . /// public override string ToString() { return builder.ToString(); } } }
And the code for the helper method
public static string ScriptInclude(this JavaScriptHelper javaScriptHelper, string actionName, string controllerName) { UrlHelper helper = new UrlHelper(javaScriptHelper.ViewContext.RequestContext); string url = helper.Action(actionName, controllerName); return string.Format("{1}", url, Environment.NewLine); }