Click here to Skip to main content
Licence CPOL
First Posted 10 Jan 2011
Views 9,026
Bookmarked 27 times

JavaScript Organization for MVC

By | 10 Jan 2011 | Article
A quick and easy way to organize what script executes for what view.

Introduction

One of my pet peeves is code organization when it comes to putting together an application architecture. I have a current application that is built in ASP.NET MVC 2, using IOC, Dependency Injection, and multiple layers of abstraction from the business layer back.

But I have found that after it was all said and done...there were .js files a plenty for performing all of the UI validation, presentation, AJAX calls, so on and so forth. Most of the scripts were in separate files, but there were also a whole bunch within the Views. Debugging and handing these off the the next developer became a challenge.

The goal was to refactor the organiztion and allow to slowly migrate to a better understanding of what executed where and what part of the script file was responsible for what View. The solution - ScriptViewPage.cs.

ScriptViewPage

The ScriptViewPage class inherits System.Web.Mvc.ViewPage, and when instantiated, adds an event handler for the PreLoad event. So when the View renders, or pre-renders, the event is fired and ScriptViewPage now handles and determines what View is executing and tries to locate the script file that is associated with it.

namespace System.Web.Mvc {     
    public class ScriptViewPage : ViewPage     
    {         
        public ScriptViewPage() 
            : base()         
        { 
                this.PreLoad += new EventHandler(_PreLoad);         
        }

Within the handler, we dig into ViewContext.RouteData to determine the Controller and View and format the .js script file name.

string viewScriptPath = string.Format("~/ViewScripts/{0}/{1}.js", 
                        ViewContext.RouteData.Values["Controller"], 
ViewContext.RouteData.Values["Action"]);

Test to see if the file exists, and using the TagBuilder, create the script tag and set the text of the Literal control on the Master template/View if the control exists.

if (System.IO.File.Exists(MapPath(viewScriptPath)))
{
   var scr = new TagBuilder("script");
   scr.Attributes.Add("type", "text/javascript");
   scr.Attributes.Add("src", ResolveClientUrl(viewScriptPath));

   Control ctrl = Page.Master.FindControl("viewScript");
   if (ctrl != null)
     ((Literal)ctrl).Text = scr.ToString(TagRenderMode.Normal);

}

Here is the complete class code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace System.Web.Mvc
{
    public class ScriptViewPage : ViewPage
    {
        public ScriptViewPage()
            : base()
        {
            this.PreLoad += new EventHandler(_PreLoad);
        }

        void _PreLoad(object sender, EventArgs e)
        {
            string viewScriptPath = 
              string.Format("~/ViewScripts/{0}/{1}.js", 
              ViewContext.RouteData.Values["Controller"], 
              ViewContext.RouteData.Values["Action"]);

            if (System.IO.File.Exists(MapPath(viewScriptPath)))
            {
                var scr = new TagBuilder("script");
                scr.Attributes.Add("type", "text/javascript");
                scr.Attributes.Add("src", ResolveClientUrl(viewScriptPath));


                Control ctrl = Page.Master.FindControl("viewScript");
                if (ctrl != null)
                    ((Literal)ctrl).Text = scr.ToString(TagRenderMode.Normal);

            }
        }
    }
}

All you need to make sure of is that the .js files are named the same as your Views.

Implementation

I needed a way to slowly refactor the existing code, but also allow for the new script organization to be used for all new View/scripts added to the application. Here is the direction I took.

  • Add a new folder to the root of the Web Application called "ViewScripts".
  • Replicate the folder structure that exists within your "Views" folder.
  • Edit Site.Master and add a Literal control to the bottom of the template above the closing body tag, and set ID="viewScript".
  • In your Views, instead of inheriting from System.Web.Mvc.ViewPage, change it to System.Web.Mvc.ScriptViewPage.

Points of Interest

There may be other ways to accomplish the same task, but this was the easiest method to take in order to not have to restructure the current application and be able to organize and go forward and have a structure to refactor to for existing scripts. Enjoy.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Shayne P Boyer

Software Developer (Senior)

United States United States

Member

Follow on Twitter Follow on Twitter
Shayne is an experienced manager, analyst and programmer with a background in a wide range of businesses including government, travel, Internet service provider, marketing, customer relationship management and real estate.
 
Complete software lifecycle analysis skills including:
 
•Needs analysis, requirements analysis, risk assessment, and cost benefit analysis.
•System requirements, functional design, detailed design, and process flow.
•Configuration management and source code control.
•System integration, system implementation, and maintenance.
•Development planning and execution for replacing legacy application with new technology.
Software and database design experience includes:
 
•Product design and implementation for web applications, Windows Desktop Applications using C# and VB.NET, .NET Windows Services and XML Web Services.
•Database design with attention towards a balance between performance and normalization.
•Database design, implementation and administration in Microsoft SQL Server.
•Data Conversions using SQL Server Integration Services from Informix, Oracle and other relational and non-relational data storage systems to SQL Server
Specialties:
 

•Software design, architecture
•Team building and management
•.NET technologies involving Windows, Web and Database development.
•Long and short term vision to deployment goals of an organization

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralMy vote is 5 PinmemberVetalRMP21:57 19 Jan '11  
GeneralMy vote of 5 Pinmemberdaltonrs@hotmail.com5:07 11 Jan '11  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120517.1 | Last Updated 10 Jan 2011
Article Copyright 2011 by Shayne P Boyer
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid