Sunday, April 7, 2013

Why I Hate JScript

Let's start off with - yes, we're talking about Active Server Pages (ASP). And no, no one is really using ASP anymore. Yet, for some reason some of us are still dealing with them. So here we go...

I've hated JScript for over a decade. When I first got into web development, ASP was the method of choice for Windows environments. Almost all the examples of code online and in books were written in VBScript. But there were those "special few" who believed that ASP pages should be written with JScript – some strange version of JavaScript. As if it made them feel more like a real programmer, and less of scripter. But let's face it, anything "they" could do in JScript, I could do in VBScript. Aside from try catch blocks, there really wasn't much difference in the languages.

And now that it is literally of no importance, as almost no one is writing ASP pages at this time, I've run across an actual technical reason to justify my disdain for JScript.

A while back I had to make some updates to a very old web application written in ASP using JScript. The application had a function where it did a search for people in Active Directory and displayed the results along with some essential attributes about the people. The search worked fine, but they wanted a new attribute to be displayed. The organization this supported stored an additional phone number about each user in active directory, which was useful to employees and partners. This phone number was stored in the Active Directory attribute called otherTelephone – which is a multivalued attribute. In our case, each person had only one otherTelephone number defined, so I knew I could always pull the first one. This is where this is a located in AD:



I updated the existing code, only to find that the otherTelephone attribute was not being displayed. I pulled the AD search and display code into a separate page to start troubleshooting the problem, but still couldn't find any way to make it work. I've since replicated the problem in my home lab, and here's the code:

<%@ LANGUAGE="jscript" %>
<%
 var oConn = Server.CreateObject("ADODB.Connection");
 oConn.Provider = "ADsDSOObject";
 oConn.Open();

 var oCmd = Server.CreateObject("ADODB.Command");
 oCmd.ActiveConnection = oConn;
 oCmd.CommandText = "<LDAP://DC=company,DC=org>;(&(objectCategory=person)(cn=*smith));givenname,sn,mail,telephoneNumber,otherTelephone;subtree";

 var oResult = oCmd.Execute();
 while (oResult.EOF == false)
 {
  Response.Write("<hr />");
  Response.Write(oResult.Fields("givenname") + " " + oResult.Fields("sn") + "<br />");
  Response.Write(oResult.Fields("mail") + "<br />");
  Response.Write(oResult.Fields("telephoneNumber") + "<br />");
  var otherPhone = oResult.Fields("otherTelephone").Value;
  if (otherPhone != null)
  {
   Response.Write(otherPhone[0] + "<br />");
  }
  oResult.MoveNext();
 }
%>

This code generates the following:


John Smith
john.smith@company.com
555-111-1112
undefined

Jane Smith
jane.smith@company.com
555-111-1111
undefined

The code isn't correctly reading the value from the otherTelephone attribute in AD. If you think that there's something wrong with the code, here's the same code that I rewrote in VBScript.

<%@ LANGUAGE="vbscript" %>
<%
 Set objConn = CreateObject("ADODB.Connection")
 objConn.Provider = "ADsDSOObject"
 objConn.Open

 Set objCmd = CreateObject("ADODB.Command")
 objCmd.ActiveConnection = objConn
 objCmd.CommandText = "<LDAP://DC=company,DC=org>;(&(objectCategory=person)(cn=*smith));givenname,sn,mail,telephoneNumber,otherTelephone;subtree"

 Set objResult = objCmd.Execute
 While Not objResult.EOF
    Response.Write("<hr />")
    Response.Write(objResult.Fields("givenname") & " " & objResult.Fields("sn") & "<br />")
    Response.Write(objResult.Fields("mail") & "<br />")
    Response.Write(objResult.Fields("telephoneNumber") & "<br />")
    otherPhone = objResult.Fields("otherTelephone").Value
    If IsNull(otherPhone) = False Then
       Response.Write(otherPhone(0) & "<br />")
    End If
    objResult.MoveNext
 Wend
%>

This code generates the following:


John Smith
john.smith@company.com
555-111-1112
x7777

Jane Smith
jane.smith@company.com
555-111-1111
x8888

And wouldn't you know it – it works just as it should in VBScript. Suck it JScript.

At the end of the day, rewriting the entire ASP page that I was updating to use VBScript wasn't an option. Remember, the code I've listed here is just part of the original page. The answer to the problem was to add a VBScript function to the existing JScript page. The code for that is listed below and renders the same HTML as the full VBScript code.

<%@ LANGUAGE="jscript" %>

<script language="vbscript" runat="server">
 Function readOtherTelephone(otherTelephone)
  If IsArray(otherTelephone) Then
   readOtherTelephone = otherTelephone(0)
  Else
   readOtherTelephone = Null
  End If
 End Function
</script>

<%
 var oConn = Server.CreateObject("ADODB.Connection");
 oConn.Provider = "ADsDSOObject";
 oConn.Open();

 var oCmd = Server.CreateObject("ADODB.Command");
 oCmd.ActiveConnection = oConn;
 oCmd.CommandText = "<LDAP://DC=company,DC=org>;(&(objectCategory=person)(cn=*smith));givenname,sn,mail,telephoneNumber,otherTelephone;subtree";

 var oResult = oCmd.Execute();
 while (oResult.EOF == false)
 {
  Response.Write("<hr />");
  Response.Write(oResult.Fields("givenname") + " " + oResult.Fields("sn") + "<br />");
  Response.Write(oResult.Fields("mail") + "<br />");
  Response.Write(oResult.Fields("telephoneNumber") + "<br />");
  var otherPhone = oResult.Fields("otherTelephone").Value;
  Response.Write(readOtherTelephone(otherPhone) + "<br />");
  oResult.MoveNext();
 }
%>

JScript is inferior. End of story.

No comments:

Post a Comment