Just a quick note: I did finally find the time to re-test the ntlmHTTP project for ColdFusion after the installation of .NET 3.5 on our ColdFusion test server (check out my earlier posts on the subject). And yes, ntlmHTTP works – at least for accessing web pages that are protected by “Windows Integrated Authentication”. Next trials will try to access SharePoint 2010…
Archive for the ‘.NET’ Category
My ‘DotnetRuntimeEnvironment’ component for ColdFusion managed to surprise me: after installing the .NET framework 3.5 the ‘
GetSystemVersion()‘ method still returned ‘
2.0.50727‘, rather than the ‘
3.5‘ or so I expected. It took some digging to find a decent explanation, but the reason appears to be mundane (at least for .NET experts): my component actually returns the version for the Common Language Runtime (CLR), and not for the whole framework (thank you, Jon Skeet!). The CLR is the runtime for the bytecode, comparable to the JVM in the Java universe.
This also means that more is needed to tell the exact .NET framework version you’re actively using – I suppose that trying to instantiate a class that first appeared in a given framework version would be a sufficient indicator. Oh well, back to the coding board, eh?
For completeness sake I can report that the code I published last week continues to work when multiple versions of .NET (CLR and/or framework) are installed on your machine.
I have been testing the ‘DotnetRuntimeEnvironment’ component I wrote about a week ago. Doing so also pointed to a better, more robust version. Here it is (the » symbol again means you should put what follows on the preceding line):
<cfcomponent name="DotnetRuntimeEnvironment" > <cfset VARIABLES.noruntime = "NORUNTIME" /> <cfset init() /> <cffunction name="init" access="private" returntype="void" output="false" > <cftry> <cfset VARIABLES.re = CreateObject( "dotnet", » "System.Runtime.InteropServices.RuntimeEnvironment" ) /> <cfcatch type="any" > <cfset VARIABLES.runtime = "" /> </cfcatch> </cftry> </cffunction> <cffunction name="isRunning" access="public" returntype="boolean" output="false" > <cfreturn IsObject( VARIABLES.runtime ) /> </cffunction> <cffunction name="GetRuntimeDirectory" access="public" returntype="string" output="false" > <cfif IsObject( VARIABLES.runtime ) > <cfreturn VARIABLES.runtime.GetRuntimeDirectory() /> <cfelse> <cfreturn "NONE" /> </cfif> </cffunction> <cffunction name="GetSystemVersion" access="public" returntype="string" output="false" > <cfif IsObject( VARIABLES.runtime ) > <cfreturn VARIABLES.runtime.GetSystemVersion() /> <cfelse> <cfreturn "NONE" /> </cfif> </cffunction> </cfcomponent>
This version will run on any platform, and give a reasonable answer for any method called – even when no .NET runtime can be found. The ‘
isRunning()‘ method allows you to check the existence of a .NET runtime before you try to work with other methods. As always, suggestions or additions are welcome!
I have had a bit of trouble to get ntmlHTTP running correctly on our servers. In response to my ticket on RiaForge, Nick Harvey clarified the dependence of the DLL on .NET version 3.5 (or higher, I suppose). I’m not a Windows nor a .NET specialist, and I don’t have many rights on the servers at work, so it took me and my collegue a bit of time to conclude that we were trying to run Nicks code on a .NET 2.0 base – and that didn’t work out, of course.
I already have a few ColdFusion pages with diagnostics about our servers, so I decided to do the right thing and add the .NET version to the existing diagnostics. It took me a while to find the exact class and method in the .NET runtime, but it turned out to be simple. So I have created a small ColdFusion CFC to help me (the » symbol means you should put what follows on the preceding line):
<cfcomponent name="DotnetRuntime" > <cfset VARIABLES.re = CreateObject( "dotnet", » "System.Runtime.InteropServices.RuntimeEnvironment" ) /> <cffunction name="GetRuntimeDirectory" access="public" returntype="string" output="false" > <cfreturn VARIABLES.re.GetRuntimeDirectory() /> </cffunction> <cffunction name="GetSystemVersion" access="public" returntype="string" output="false" > <cfreturn VARIABLES.re.GetSystemVersion() /> </cffunction> </cfcomponent>
Once you have that component, it’s pretty simple to use it – just put this in a .CFM (I’m supposing you have called your CFC ‘
DotnetRuntime.cfc‘ in the current directory):
<cfsilent> <cfset dotnet = CreateObject( "component", "DotnetRuntime" ) /> </cfsilent> <cfoutput> <html> <body> <h1>Dotnet Runtime Environment</h1> <p> This ColdFusion server is currently running <b>.NET version #dotnet.GetsystemVersion()#</b> from directory '<code>#dotnet.GetRuntimeDirectory()#</code>' </p> </body> </html> </cfoutput>
So there you have it. I know this works in our setup, but I don’t know what will happen when there are multiple .NET runtimes on your machine… That’s why I wrapped the code into a CFC – functions to detect specific versions of .NET, handle multiple runtimes, etc. can thus be added in a single component for easy versioning and maximum reuse. Suggestions or additions are welcome!
PS. I have left the “hint” attributes out of the code above, because I haven’t yet found a good way to publish program code in WordPress.
We have been trying out the 0.2 version of the ntlmHTTP project for ColdFusion, in order to see if we could call the SharePoint webservices. Unfortunately, POSTing a SOAP request never works: we always end up with a nasty error message for any of the new methods. Here’s a sample message:
Could not find the generic method Com.Bluemini.CF.NetHttpRequest.setUsername
.class files that ColdFusion generates to integrate the DLL shows that the methods are there, just like a
CFDUMP of the object we create. But CF8 (on a Windows 2003 server) seems unable to call them… I’ll download the source code and pass it on to our local .NET guru for examination. I’ll keep you posted about the results of our investigations (that may take a few days, though).
At work, we have tried the initial version of the
ntlmhttp project on RiaForge (see my post from last week as well). We’re (still!) on CF8, installed in a minimal way, so I had to install the .NET integration layer first. But that is fairly simple:
- Download and install the Download ColdFusion 8 .NET Integration Service Installer (EXE, 44.8 MB) from the Adobe site.
When that is done, you just download the
- Put the DLL on your file system, and write down the path.
- Now run this script to check your installation:
<cfset NetRequest = CreateObject( "dotnet", "Com.Bluemini.CF.NetHttpRequest", "/path/to/your/NetHttpRequest.dll") />
<cfdump var="#NetRequest#" />
So far, so good: calling a (secured) webpage worked too. From the almost non-existent documentation it isn’t clear to me how we might use this to issue a SOAP request – we’ll see about that later.
When trying out the component with a web service call, I need to remember not to add the domain prefix to the username required in the call parameters. That’s different from what we need for our
CFHTTP calls, but not too hard to do. I just wonder: is it the component that makes it possible to skip the domain name, or is it the configuration of our Windows network?