Sunday, July 25, 2010

VS2010: Visual Studio 2010 - finding web reference option when working with Windows Forms Applications

Something I ran into today made me do a double take. This could have originated from the initial configuration choice I made when setting up Visual Studio 2010 or the tool is trying to be so smart it starts to get confusing..


However it happened, it does seem to make things more difficult when trying to create windows form applications. In particular, if you want to use a web-reference in your regular windows application the number of clicks has increased and discoverability has decreased.

Adding web-references to consume web services in ASP.NET application is not impacted by this change. In particular the context sensitive links to add web-reference are gone when I am in the Solution Explorer working on a Windows Form Application.






Instead the only thing you can seemingly do is to add a service reference. Though you can start here, web services that are registered through this channel do not behave at all like the previous releases of Visual Studio. Thus, beware, this is not what you want to do if you want to consume a regular web service, especially ones that are not created with VS to begin with. To get to the plain Jane adding of a web service you have to walk through some additional steps.

A) Select the "Add Service Reference..." option, then, click on the "Advanced..." button.





B) Click on the "Add Web Service" button from the advanced screen:




Allright that should do it to bring you back into the old web service ways.

Cheers,

B

Saturday, July 17, 2010

CF: The varExists() function -- Expanding IsDefined() to work with regular array and associative array notations.

Many times while working in ColdFusion code I am encountering the simple need to check for the existence of an index in an array, e.g. myArray[3]. While other languages may have had easier checks on this, in Adobe ColdFusion, I unfortunately, have to work around this scenario with many lines of code or different functions to call. Thus, I am able to construct fully well formed variable references and use them, but cannot check their validity in a simple fashion.

For example, I can't do a simple call to a universal function such as IsDefined("myVar[3]"). In this simple scenario we could have used ArrayIsDefined(), however, the scenarios I normally deal with are not so simple. In my scenarios I am not sure about whether "myVar" is an array in the first place or whether the index is numeric. E.g. I may need to check myVar[checkIndex]; this maybe a strucure with an associative array notation which takes me back to square one. Along these lines, multi-dimensional arrays such as myArray[3][4] are equally unqualified for ArrayIsDefined().

Similarly associative array notations that can be used with structures, e.g. myStruct["testNode"], equally do poorly on these checks and could require some sort of special checking and more lines of code.

How about a combination of things:
TestStruct.Animals['species'][1]['counts'][2]

All of these scenarios go beyond the ability of IsDefined() or other functions and cause more code to be written. Maybe this would be an opportunity to expand in future version of ColdFusion but for now we're stuck or are we? (yeah, rhetorical question this one).

I made this a test project and developed an alternative function, varExists(), to IsDefined(); it may not be usable in all scenarios but will come in handy in coding.
The sample implementation can be downloaded here (varExists.zip (3KB)).

The first objective was just to be able to handle the complex notation scenarios that commonly fail under IsDefined().

e.g.:
varExists("TestStruct.Animals['species'][1]['counts'][2]") should operate without a hitch on complex variable notations. While at the same time maintaining full backward compatibility with IsDefined(). So you should be able to do things like this varExists(varName), varExists should check for the existince of the content referenced by the content of varName, e.g. a string such as "TestStruct.myArray[2][1]".

But, why stop there, the next thing that I commonly do once I check for the existence of a variable is to retrieve its value for some sort of operation, so I added this option as second argument. Thus, varExists will automatically return the value referenced as part of its operation if "True" is passed as second argument, e.g. varExists("myUserArray[33]",true). This would return the UserName at array index position 33.

Another common task I perform when the value is not known or "undefined" is to assume a default value. Thus, I added this as third parameter. When a third parameter is supplied it will be returned, when the actual variable reference is undefined.
For example:
varExists("myUserArray[33]",true,"John Doe")
would return "John Doe" if the array index 33 is not populated for some reason.

The example code has the test array and unit tests with sample scenarios. The hope is that eventually the ColdFusion language can accommodate these type of operations natively.

Happy experimenting.

Cheers,

B.

Addition:

The Railo CFML engine does not exhibit the flaw outlined in this article. Thus, if you use Railo, you probably will not encounter scenarios in which you can construct a valid variable reference but cannot check for its existence. The IsDefined() function works as expected, however, if you want the expanded functionality of retrieving variable values etc. you would still need to use the varExists() User Defined Function (UDF) provided here.

Best,

B.