.Net Jobs

The October issue of Dr. Dobbs Journal has a small article called Quantifying Popular Programming Languages. This article is unfortunately not available on-line for free. Dr. Dobbs surveyed web-based job boards to see what percent of the job postings contained references to specific programming languages, but they did not divulge which boards they surveyed. The survey lasted from July 2002 to June 2003. Only 16.4% of the jobs posted contained references to .Net, 5.35% mentioned VB.Net specifically, and 5.16% mentioned C#.  Java ocurred in over 40% of the ads and C++ was in over 50% of the ads. Visual Basic was in 19.2% of the ads. Does this reflect a slow adoption of .Net? Or is this just an effect of the economy, or both? I have lurked around the MCAD usenet group and seen frequent comments about the lack of jobs specfically for .Net. Of course, my company is certainly not hiring (see my post here), and the project I am on is the only .Net project in the company. In my experience the benefits of .Net development are significant compared to what we were doing in the past, even for the customer. Are we just not getting through to the business decision-makers about where we need to go? Or should I really spend more time learning C++?

Posted: Wednesday, October 15, 2003 6:57:28 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
None

OS = Windows 98

In response to: http://dotnetjunkies.com/WebLog/donnymack/posts/2383.aspx

 You are Windows 98.  You're a bit flaky, but well-liked.  You don't have a great memory, but everyone seems to know you.  A great person to hang out with and play some games.
Which OS are You?

Posted: Thursday, October 09, 2003 4:55:18 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
None

Business Objects Dead?

There a fascinating discussion going on at Tim Sneath's blog about the functionality of the business layer moving to compiled stored procedures in Yukon. At least in my project, we have been doing that very thing and struggled with the n-Tier issue as a result. In our case, the database is Oracle 8i, and the application is/was ASP, which we are now converting to .Net. We have some very complex business logic encapsulated in PL/SQL stored procedures. There were two concrete reasons for the decision:

  1. The amount of data that would need to be transferred was huge.
  2. Oracle is more efficient than ASP code at many of the operations involved.

With ADO.Net, some of the ineffieciency may be addressed, but the database is designed for efficiency at certain operations that ADO.Net won't be able to match.

We did not need to approach this from a scalability issue, as the app receives hundreds of hits per hour, not thousands or more. I still think it will scale OK as your business objects will have much shorter life spans and you can still pool and queue database connection objects if needed due to long-running stored procedures.

Posted: Monday, October 06, 2003 12:57:15 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
Programming

Very Long Week

My company just spent 3 days laying off tons of people. I survived this round, but the development group I am a part of lost three people. The company was about 8000 people worldwide, I wonder what it is now. Management is not interested in distributing the details. It's pretty rough watching the CIO follow around the HR team that is laying people off, and then getting to listen to them cleaning out the cube on other side of the wall.  I am fortunate to have a good project that lets me learn .Net. If my turn comes at least I am acquiring new skills.
Posted: Friday, September 26, 2003 12:23:27 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
None

Data Access Application Block and Oracle

I read about the Data Application Block yesterday and was intrigued, although for the life of me I cannot remember where I read about it originally to pass along some credit. So I checked it out and it is very nice and all, but alas my project uses Oracle not SQL Server. Initially I thought about porting it to Oracle, but I figured that it has already been done. So I did a little Googling and voila!, Microsoft themselves had already done the work in the Nile 3.0 demo application. Sadly, it was in C# and my current project is using Oracle and VB.Net. So now I am back to porting.

Posted: Friday, September 19, 2003 12:43:39 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 1.1 | ADO.Net | Oracle

Query a Novell LDAP server with VB.Net

Once again, I am amazed at how simple tasks have become using .Net. Something I thought would be complex turns out to be completely handled by the framework. Kudos to the .Net team.

For my current project, I need to validate that a person is an internal employee before allowing them continued acccess to the web site. My company uses a Novell infrastructure, and luckily has an LDAP server that I can access for employee validation.

Luckily, Novell provides a resource for developers to begin working with LDAP at the Novell Developer Labs. You can create an account and query their server for free. So that is where I started, but eventually the Novell network admins in my company got around to my request and I was able to use the code almost without modification against our internal server.

Here is my quick console application I created to test against the Novell Developer Lab LDAP site (my container name is Fender and my login is admin.  The only modifications I had to do to get it to work with my company's LDAP server was to learn the container names and the fields I could query.  

Imports System.DirectoryServices

Sub Main()
Dim
ds As New DirectorySearcher
Dim resultset As SearchResultCollection
Dim result As SearchResult
'Return the securityEquals field and the cn field
Dim ResultFields() As String = {"securityEquals", "cn"}

With ds
    'Set the container I want to search (.admin.Fender.user.novell)
    .SearchRoot = New DirectoryEntry(
LDAP://192.108.102.215/ou=Fender,ou=user,o=novell)
    'Use the array set above for return fields
    .PropertiesToLoad.AddRange(ResultFields)
   
'Set a filter/query
    .Filter = "cn=ad*"
End With

Try
  
'Perform the search

   
resultset = ds.FindAll()
    If resultset.Count > 0
Then
       
For Each result In resultset
            Console.WriteLine(result.Properties("securityEquals")(0))
       
Next
    Else
        'No results
       
Console.WriteLine("No Data Found")
    End If

Catch ex As Exception
   Console.WriteLine("Error: ")
   Console.WriteLine(ex.Message)
End Try

End Sub

Posted: Friday, September 12, 2003 2:43:44 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 1.1 | Novell | Security

Excel as a Web Service Client

As a small project, we were tasked with creating a data feed from a text report genereated by JD Edwards (not OneWorld, an older version) and our application. Instead of going the FTP and text file parsing route, I decided to try our first venture into a web service. Since the JD Edwards group were using Excel 2000 to manipulate the report before sending it to our system, I figured a VBA macro could send the data for them, using the XMLHTTP object.

'Notes: Using late binding so the project won't need explicit references
'       Using MSXML 2.5 object model to be sure it will run on most PCs
Public Sub SendDataToEnCore()
    Dim oXML As Object
    Dim oDom
As Object
    Dim oNode
As Object
    Dim sXML As String
    Dim nResult As Integer
    Dim sResponse
As String
     
    On Error GoTo Handler
    Set oXML = CreateObject("Microsoft.XMLHTTP")
    Application.Cursor = xlWait 'Change the cursor to a wait cursor
    Application.ScreenUpdating = False   'Stop screen redraw
    With oXML
         'Call the service, it only takes one parameter, the XML string

        .Open "POST", & _
       
"http://test.com/Redeployment.asmx/Redeployment_Update", False
       
        'The following line is necessary for the web service to recognize the post
        .setRequestHeader "Content-Type", "application/x-www-form-urlencoded"

        Application.StatusBar = "Waiting for a response..."
        'Create XML is a function that loops the spreadsheet building an XML string
        .Send CreateXML
 
   End With
   
    sResponse = oXML.responseText
    With Application
        .Cursor = xlDefault
        .StatusBar = ""
        .ScreenUpdating = False
    End With
    Set oDom = CreateObject("MSXML.DOMDocument")
    oDom.loadXML (sResponse)
   
    If oDom.hasChildNodes Then
        'Display the resulting message from the web service
        Set oNode = oDom.documentElement.firstChild
        nResult = MsgBox(oNode.Text, vbInformation, "EnCore Data Transfer")
    Else 'No response at all
        MsgBox ("The JDE upload failed. Please contact Development
for assistance.")
   
End If
    Set oXML = Nothing
    Set oDom = Nothing
    Set oNode = Nothing
    Exit Sub
Handler:
    With Application
        .Cursor = xlDefault
        .StatusBar = ""
        .ScreenUpdating = False
    End With
    MsgBox Err.Description
    Set oXML = Nothing
    Set oDom = Nothing
    Set oNode = Nothing
End Sub

So far this has worked well for us. One of the issues we encountered was URLEncoding the XML string before sending it. Otherwise, it just won't parse properly on the web service end. Here is an abbreviated version of the web service function that is called by the above Excel VBA function.

Public Function Redeployment_Update(Byval sInput As string) As String

    Dim dt As DataTable
   
dim n as Integer

    sInput = cstr(sInput)

    n = sInput.Length
    If n <= 0 Then
       
return "File contains no data"
   
End If

    ' Load the input XML string into a DataTable
    dt = LoadDataTable(sInput)

   
Dim drCurrent As DataRow
    For Each drCurrent In dt.Rows
       
ProcessRow(drCurrent) 'Our custom function to parse a row
    next

   
return "File received OK. Characters Received=" & n

End Function

Posted: Monday, September 08, 2003 1:23:20 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 1.1 | Office

Impersonation

All right, now that I have done a bunch of talking, how about some code? I stumbled across this recently while pouring through MSDN. The code lets you impersonate any other user, provided you know the credentials. In our case we needed to become the IIS user so we could access files on a remote file server. In our situation, there are multiple web applications within our domain, so the network admin has set up the IIS sites to all use a common domain-wide anonymous user, so it is easier for him to manage permissions. As we are the first .Net project, the ASPNet user has no rights whatsoever on the network. We talked with the admin and he was not interested in giving the ASPNet users from a bunch of different web servers rights to other network resources. We looked at changing the ASPNet user credentials Machine.config, but this broke debugging locally immediately. So I looked into impersonation and found out how to impersonate the IIS user in code:

Imports System.Security.Principal

Function impersonateAnonymous() As WindowsImpersonationContext

     'Grab the current Http context
    
Dim context As HttpContext = HttpContext.Current

    'Set up a Service Provider based on this context
     Dim
iServiceProvider As iServiceProvider = CType(context, iServiceProvider)

     'Create a type which represents an HTTPContext
     Dim
httpWorkerRequestType As Type = GetType(HttpWorkerRequest)

     'Get the HttpWorkerRequest service from the service provider
     Dim
workerRequest As HttpWorkerRequest = _
         
CType(iServiceProvider.GetService(httpWorkerRequestType), HttpWorkerRequest)

     'Get the token passed by IIS from the workerRequest service
     Dim
ptrUserToken As IntPtr = workerRequest.GetUserToken()

     'Create a Windows Identity from the token
     Dim
winIdentity As New WindowsIdentity(ptrUserToken)

    'Send back the IIS identity
     Return
winIdentity.Impersonate

End Function

To use the function, simply call it like so before the code that needs proper permissions:

Dim impContext As WindowsImpersonationContext = impersonateAnonymous()

Now the subsequent lines of code operate in the context of the user assigned to IIS. And then when you are done impersonating:

impContext.Undo()

I based this function on some C# code I found in a Patterns & Practices document on MSDN: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/thcmch10.asp

Posted: Tuesday, September 02, 2003 6:00:54 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 1.1 | ASP.NET | Security

Impersonation

All right, now that I have done a bunch of talking, how about some code? I stumbled across this recently while pouring through MSDN. The code lets you impersonate any other user, provided you know the credentials. In our case we needed to become the IIS user so we could access files on a remote file server. In our situation, there are multiple web applications within our domain, so the network admin has set up the IIS sites to all use a common domain-wide anonymous user, so it is easier for him to manage permissions. As we are the first .Net project, the ASPNet user has no rights whatsoever on the network. We talked with the admin and he was not interested in giving the ASPNet users from a bunch of different web servers rights to other network resources. We looked at changing the ASPNet user credentials Machine.config, but this broke debugging locally immediately. So I looked into impersonation and found out how to impersonate the IIS user in code:

Imports System.Security.Principal

Function impersonateAnonymous() As WindowsImpersonationContext

     'Grab the current Http context
    
Dim context As HttpContext = HttpContext.Current

    'Set up a Service Provider based on this context
     Dim
iServiceProvider As iServiceProvider = CType(context, iServiceProvider)

     'Create a type which represents an HTTPContext
     Dim
httpWorkerRequestType As Type = GetType(HttpWorkerRequest)

     'Get the HttpWorkerRequest service from the service provider
     Dim
workerRequest As HttpWorkerRequest = _
         
CType(iServiceProvider.GetService(httpWorkerRequestType), HttpWorkerRequest)

     'Get the token passed by IIS from the workerRequest service
     Dim
ptrUserToken As IntPtr = workerRequest.GetUserToken()

     'Create a Windows Identity from the token
     Dim
winIdentity As New WindowsIdentity(ptrUserToken)

    'Send back the IIS identity
     Return
winIdentity.Impersonate

End Function

To use the function, simply call it like so before the code that needs proper permissions:

Dim impContext As WindowsImpersonationContext = impersonateAnonymous()

Now the subsequent lines of code operate in the context of the user assigned to IIS. And then when you are done impersonating:

impContext.Undo()

I based this function on some C# code I found in a Patterns & Practices document on MSDN: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/thcmch10.asp

[Originally posted at http://www.dotnetjunkies.com/WebLog/davetrux/archive/2003/09/02/1360.aspx]

Posted: Tuesday, September 02, 2003 6:00:05 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback

Migrating our ASP app to .Net

We are migrating an ASP app to ASP.Net, but not all at one time as my business customers within the company won't pay for that kind of time all at once. So we are migrating piece-by-piece as we develop new functions within the app. Our plan is to develop all new pages using .Net, and convert classic ASP pages as we have to touch them due to new development. To get the remaining pages converted, we are just going to squeeze them in as often as possible along with the new development, mostly on a one or two at a time basis. So probably of the next 6-12 months the ASP and ASP.Net applications will coexist and appear to the users to be one application.

Right now, we have done what we considered the basic conversion necessary to implement our plan:

  • Convert the login process to .Net. We are using Forms authentication since users are checked from our own database. We may migrate this to LDAP sometime in the future. My company uses Novell Netware for network login and GroupWise for email. I would love to hear from anyone who has a web app that can create appointments in GroupWise!!
  • Move frequently used Session variables to cookies. Luckily, we were not using lots of Session variables in the classic ASP. We encrypt all the data written to the cookies so spoofing is harder. We are currently not a web farm, but that is also in our future so the Session variables need to go anyway.
  • Create a common time-out scheme between the applications using a cookie. The ASP app times out after 35 minutes of inactivity for what the HR folks call “security“, as the app contains lots of personal information about both employees and non-employees.
  • Convert common functions to .Net (like checking user roles, encryption, database access, search engine, etc.)
  • Convert ASP includes for page structure into .ascx files.

Of course, none of this has gone into production yet (sigh...). It is on the test sever and hopefully will roll out by the end of the month.

Posted: Tuesday, September 02, 2003 5:22:45 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 1.1 | ASP.NET | Novell | Oracle