Luke Smith Write today, wrong tomorrow

JavaScript variable generation for ASP.NET MVC

RC1 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);
        }
comments powered by Disqus