Employing Script Injection Techniques with ASP.NET

Boost Your Client-side Processing

asp:Feature

LANGUAGES: VB.NET

ASP.NET VERSIONS: 2.0

 

Employing Script Injection Techniques with ASP.NET

Boost Your Client-side Processing

 

By John Paul Mueller

 

Scripts form an important part of most Web applications because they let you perform tasks at the client. Relying on the processing power that the client can provide is an important way to reduce the amount of processing the server must perform. In addition, using client-side processing can improve performance for the user because the data doesn t have to make continuous round trips between the client and server. Finally, you must perform certain tasks on the client simply because you need client resources. For example, you normally perform cookie processing on the client, and some security techniques rely on client-side processing. For all these reasons, and more, client-side processing is important. However, trying to figure out how to perform the client-side processing can be difficult in some cases, especially when the script must perform some unique action based on the client or the user. I ve seen developers use any number of odd scripting techniques (usually with compatibility problems) to overcome limitations in scripting.

 

Script injection techniques provide a means of working around scripting issues that is both simple and elegant. You use script injection to create a script on the fly based on the client s request to the server. Consequently, the resulting script is simpler because you don t need to test for a number of situations, it performs better because there s less code, and it still provides superior processing flexibility because you can design the script to meet the specific needs of a particular client. In addition, you can do something that a standard script can t. Say that the user is an administrator (versus a power user). You can use script injection to tailor the script with additional capabilities for an administrator. The technique is safe because the script doesn t exist until you create it in code on the server. Every user sees a script that the server-side code tailors to their specific needs and with their security rights in mind. In short, script injection offers you a way of creating user-specific scripts that greatly enhance system security because no one obtains any code they shouldn t use.

 

A Simple View of Script Injection

The .NET Framework provides a vast array of classes, methods, and properties you can use to create a script. In fact, there are so many elements that it s easy to lose sight of the fact that scripts can be quite simple and easy. All you really need to know is that you need a piece of text that contains the script, a control on the Web page to execute the script, and the ClientScript property. That s it. This first example looks at the simple view of script injection. Let s begin with a control or two. I ve added a simple Label and Button to a Web page, like the one shown here:

 

 Text="A Simple Script Injection Test" />

 Text="Click Me" OnClientClick="SayHello()" />

 

The SayHello script doesn t actually exist yet. The code-behind for this Web page will inject the script as part of the Page_Load event handler. Figure 1 shows the code for this simple script example.

 

Protected Sub Page_Load(ByVal sender As Object, _

             ByVal e As System.EventArgs) _

             Handles Me.Load

  ' Holds the injected script.

  Dim TheScript As New StringBuilder()

  ' Create the script.

  TheScript.Append("")

  ' Inject the script.

  Me.ClientScript.RegisterClientScriptBlock( _

     Me.GetType(), "HelloScript", TheScript.ToString())

End Sub

Figure 1: Adding the script injection code.

 

The script creation process involves three steps. Create a ScriptBuilder object to hold the script (this helps with performance), define the script, and add the script to the Web page using the RegisterClientScriptBlock method. Notice that the RegisterClientScriptBlock method requires that you provide the host type using Me.GetType, a key you can use to identify the script, and the script itself. As shown in Figure 2, the script appears within the body of the Web page when the user requests the page. You can right-click the Web page and select View Source from the context menu to see this code.

 


Figure 2: The script appears within the Web page as if you placed it there yourself.

 

Figure 2 also points out something that I do to make life easier for me. I normally add formatting to the injected script. It s not that the browser cares about the formatting, but when I use formatting, I can see the output of my script far more easily, which makes debugging significantly easier, as well. Often I can simply look at the output and see an error without having to work too hard. When you click Click Me, the Web page displays an alert containing the word Hello, even though this script doesn t actually exist until the page loads. This simple example demonstrates part of the magic of using injection scripts.

 

Creating Situational Scripts

It s time to look at a more difficult example. Let s say you want to create a script for a company Web site that displays a meeting or other commitment popup on specific days based on the user s needs and the needs of your company. In addition, let s add a little complexity by making this a startup script so you can t use a standard script block to inject it. In this case, you don t need to add any controls to the Web page at all; the script executes automatically when the Web page loads. Figure 3 shows the code for this example.

 

Protected Sub Page_Load(ByVal sender As Object, _

                       ByVal e As System.EventArgs) _

                       Handles Me.Load

  ' Open this page only on Tuesdays.

  If DateTime.Now.DayOfWeek = DayOfWeek.Tuesday Then

     ' Holds the injected script.

     Dim TheScript As New StringBuilder

     ' Display a page based on the user's rights.

     If User.IsInRole("Administrator") Then

         ' Create the script.

        TheScript.Append("window.open('Admin.ASPX', ")

        TheScript.Append(vbCrLf)

        TheScript.Append("   'Admin', ")

        TheScript.Append(vbCrLf)

        TheScript.Append("   'height=300, width=400',")

        TheScript.Append(vbCrLf)

        TheScript.Append("   'resizable=true',")

        TheScript.Append(vbCrLf)

        TheScript.Append("   'dependent=True');")

        TheScript.Append(vbCrLf)

     Else

        ' Create the script.

        TheScript.Append("window.open('Meetings.ASPX', ")

        TheScript.Append(vbCrLf)

        TheScript.Append("   'Meetings', ")

        TheScript.Append(vbCrLf)

        TheScript.Append("   'height=300, width=400',")

        TheScript.Append(vbCrLf)

         TheScript.Append("   'resizable=true',")

        TheScript.Append(vbCrLf)

        TheScript.Append("   'dependent=True');")

        TheScript.Append(vbCrLf)

     End If

     ' Verify that the script doesn't already appear

     ' on the page.

     If Not _

        Me.ClientScript.IsStartupScriptRegistered( _

           Me.GetType(), "Meeting") Then

        ' Add the script to the Web page.

        Me.ClientScript.RegisterStartupScript( _

           Me.GetType(), "Meeting", _

           TheScript.ToString(), True)

     End If

  End If

End Sub

Figure 3: Creating a situational script.

 

The code begins by checking the day of the week. It only displays the popup meeting message on Tuesday. This is the first level of customization. Yes, you could do the same thing with a script embedded in the Web page, but the script would always be there and there s a chance that someone would use the presence of that script to circumvent controls and policies your company has in place. For example, a user could see the meeting list by simply changing the date on their computer. Perhaps, for security reasons, you only want users to see the meeting list on Tuesday. Using this approach, the script doesn t even exist until Tuesday, so no one can cheat.

 

After the code determines that it s the right day of the week, it uses the user s role to tailor a script for the user s needs. Don t let the simplicity of the example fool you. This second level of customization is quite powerful. You could tailor a script for a particular user. In fact, you could tailor the script for a particular user for each day of the week and based on their location. The concept here is that you don t have to provide any more functionality than the user actually requires when accomplishing a task. In this case, the example displays a different popup based on the user s role. A general user can t access the administrator s popup because the script won t contain the proper location. Of course, you ll further protect the administrator s pages by employing proper security.

 

You always have the choice of verifying whether a page already has a particular script registered by checking with the appropriate registration method. In this case, the code relies on the IsStartupScriptRegistered method because the example uses the RegisterStartupScript method instead of the RegisterClientScriptBlock method used earlier. If someone has already registered a startup script, then the code won t register this one. You can use this feature to ensure proper script injection when relying on master pages or embedding one page within another.

 

The RegisterStartupScript method creates the script in a different location than the RegisterClientScriptBlock method, and it adds the script to the Page object. Consequently, the Web page executes the script when the page loads. The input arguments include the host type, a key for accessing the script, and the actual script text. Setting the fourth argument to True automatically adds the required