Invalid Use of Default Parameter

For some unknown reason I’m connecting to a Oracle 10g database via ODBC (from .Net! don’t ask). I was adding some new code to a existing project which I’d manage to get to use IDataReader and such so that if one day I decided to switch from ODBC it would be easy.

However all the old code uses SQL strings for updates and inserts and I decided it would be much better to use IDbCommand and IDbDataParameter.

So currently we had this:

Dim sql as String = “INSERT INTO TABLE1 (VAL1, VAL2, VAL3, VAL4, VAL5) VALUES (‘” & Val1 & “‘, ” & Val2 & “, ” & Val3 & “, 0, Null)”

Using comm As IDbCommand = connection.CreateCommand()

  comm.CommandText = sql

  comm.ExecuteNonQuery()

End Using

which quite frankly is just impossible to read once you’ve got more than about 5 parameters.

So I changed it to look like this instead:

Dim sql as String = “INSERT INTO TABLE1 (VAL1, VAL2, VAL3, VAL4, VAL5) VALUES (?, ?, ?, ?, ?)”

Using comm As IDbCommand = connection.CreateCommand()

  comm.CommandText = sql

  Dim param as IDbDataParameter = comm.CreateParameter()

  param.DbType = DbType.String

  param.Value = Val1

  comm.Parameters.Add(param)

  param = comm.CreateParameter()

  param.DbType = DbType.Int32

  param.Value = Val2

  comm.Parameters.Add(param)

  comm.ExecuteNonQuery()

End Using

Much more verbose obviously, but much easier to read. And if you add lines to set ParameterName to something that actually means something then you can easily find the line you want and edit it. (Oh, and it also protects from the likes of Sql Injection attacks, not something I’m actually worried about on this app, but good practices are good for a reason).

Then I came to trying to set a particular field to Null, or rather a particular field value is null (a string in this instance) and therefore null should be passed to the database.

Dim param as IDbDataParameter = comm.CreateParameter()

param.DbType = DbType.String

param.Value = StringProperty

 If StringProperty is null then this falls over with the “Invalid Use Of Default Parameter” error that is the title of this post. So I found this blog post that says its cause I’m trying to set a field to null that can’t be null:

Link to SteveX Compiled » Blog Archive » Invalid Use of Default Parameter

Well, this field CAN be null, so ner! So its obviously a problem with the parameter.

Now IDbDataParameter has a property called IsNullable, which is returning false. However on the IDbDataParameter interface its a readonly property, so can’t be set. I tried casting it to a OdbcParameter and then setting it to True, which it allowed, but still fell over with the error above (plus it removed my nice DB independent code).

Turns out when you’re talking to a database you need to use the DbNull.Value property. So the following works:

Dim param as IDbDataParameter = comm.CreateParameter()

param.DbType = DbType.String

param.Value = IIf(StringProperty Is Nothing, DbNull.Value, StringProperty)

Personally I hate to use IIf, as its just not a very nice language construct (unlike the C# ? operator) but in this instance it works fine. You don’t need to use the IsNullable property at all.

[tags]sql, .net, programming, database, parameters, odbc[/tags]

Robin Returns

One of the blogs I regularily read [1] just pointed me to this article on the BBC web site. Looks like Robin Hood gets another series, hurrah! The first one has been good fun so far – very silly on occasion, but I find the love story quite interesting, and it seems to appeal to Caroline.

[Via]

[1] Waves at Les. 

Implement “Donut Caching” with the ASP.NET 2.0 Output Cache Substitution Feature

 

Scott Guthrie has produced yet another brilliant blog post on a new feature in ASP.Net. To be frank I never used the old ASP.Net 1.1 caching (bad me!) but I fully intent to use this new feature as soon as I’m developing my next web app (VB.Net windows app at the moment).

Link to ScottGu’s Blog : Tip/Trick: Implement “Donut Caching” with the ASP.NET 2.0 Output Cache Substitution Feature

[tags]asp.net, caching, programming, .net, dotnet[/tags]

Timers and Threads in .Net

I recently came across the following ‘gotcha’ which once you know about it seems really obvious, but was driving me up the wall.

Side Note: Timers in .Net

In Visual Studio 2003 there are 2 timers availabe from the toolbox, System.Timers.Timer and System.Windows.Forms.Timer.

The Forms.Timer is the one that exhibits this problem (and is shown in the “Windows Forms” section of the toolbox), while the Timers.Timer does not (and it is shown in the “Components” section of the toolbox.

In Visual Studio 2005 the System.Timers.Timer also doesn’t exhibit this problem, but it is no longer available from the toolbox!

The Problem

I wanted to run some intensive code on a regular basis, without blocking the UI, i.e. starting it from a Timer on a different Thread. However the work could take a variable length of time so I wanted to stop the timer, and then start it again when the work was finished.

Imagine the following code in the Tick event of a timer:

private void timer1_Tick(object sender, EventArgs e)
{
  timer1.Stop();
  Timer1Label.Text = DateTime.Now.ToString();
  System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(Timer1Worker));
  thread.Start();
}

and then the Timer1Worker method looks like this:

private void Timer1Worker()
{
  Random rand = new Random();
  System.Threading.Thread.Sleep(rand.Next(1, 10) * 1000);
  timer1.Start();
}

Well there will never be a second ‘Tick’ from the timer, even though interogating timer1 will reveal that the timer is enabled. The reason for this is to do (I assume) with threading. The timer is ‘attached’ to the UI thread – which is the reason you started the new thread in the first place, so the UI is not frozen during the worker method. However this new thread doesn’t seem to have the right kind of access to ‘kick’ the timer where it hurts when it wants to start it up again.

Why oh why doesn’t this throw an exception? I don’t know, but it doesn’t – it just silently fails.

The Solution

The following version of Timer1Worker fixes the problem. Notice the Invoke at the end of the method.

private void Timer1Worker()
{
  Random rand = new Random();
  System.Threading.Thread.Sleep(rand.Next(1, 10) * 1000);
  this.Invoke(new MethodInvoker(timer1.Start));
}

Another Solution (.Net 2.0)

An alternative would in .Net 2.0 is to use the Background Worker as so:

private void timer2_Tick(object sender, EventArgs e)
{
  timer2.Stop();
  Timer2Label.Text = DateTime.Now.ToString();
  backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
  Random rand = new Random();
  System.Threading.Thread.Sleep(rand.Next(1, 10) * 1000);
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  timer2.Start();
}

The RunWorkerCompleted event is fired on the correct thread (i.e. the one that the RunWorkerAsync was fired from) and solves the problem.

[tags]programming,bug,.net[/tags]

Big Developer Announcements from Microsoft

Tim Heuer was the first I’ve spotted of what I’m sure will be quite a few announcements about the final release of .Net Framework 3.0. Apparently they have also released a small product call ‘Microsoft Office 2007’ to go along with  the .Net Framework, but I’m more interested in the later :)

Here you check the cost of Windows 7.

We’ve also been given the Visual Studio tools for Windows Workflow, while the ones for WPF, WCF and Sharepoint development are new CTPs (Community Technology Previews).

A big day for Microsoft developers I reckon.

Link to devconnections day 1: big dev announcements

[tags]microsoft,.net,dotnet,wpf,wcf,wf,.netfx3,programming[/tags]

Source: https://saveonit.com/.

Flickr.Net API – Example Web Site

I’ve created a quick example Flickr.Net web site in Visual Studio 2005, for both VB.Net and C#.

There is a simple page that performs authentication, and stores the resulting authentication details in the session variables.

There is also a very simple photo album, showing the latest 20 photos from your photo stream.

The sample has been uploaded the the ‘Examples” page of the FlickrNet Wiki on CodePlex.

Any questions then let me know.

Link to FlickrNet API Examples Page 

[tags]flickr, flickrapi, programming, flickrnet[/tags]

FlickrNet API Library updates

 I’ve done a batch of bug fixes and updates to the FlickrNet API library, including Photos.DateAdded which tells you when a photo was added to a group, and the PhotosRecentlyUpdated method which details your recently updated photos.

Download from Codeplex

I’ll roll up a release in a week or so if there are no more changes before then.

FlickrWebCam

A new application using the Flickr.Net API Library has been launched. Basically allows easy and quick uploading of your web cam images onto Flickr! Cool or what.

Possibly based on the Coding 4 Fun article that tells you how to hook up a web cam using Visual Studio 2005 it looks like everything I was gonna write following my Flickr article (which I can’t find at the moment).

Link to FlickrWebCam

[tags]flickr, webcam, flickrnet, flickrapi, programming[/tags]

VB.Net vs C# in Visual Studio 2005

Strangely enough considering my background using Visual Basic and programming in Access (since version 1.1 no less, back in the day it was called Access Basic) and developing web sites using ASP when .Net came out I switched straight away to C# and wished never to look back.

However recently I’ve had a choice, rewrite 1000’s of lines of VB 6 code (amounting to over 5MB of pure code), across 10 COM objects manually into C#, or use the Visual Studio 2005 Conversion tool and start using VB.Net. Funnily enough I chose the later.

This has given me my first real world chance to actually use VB.Net, rather than just reading small code snippets on web sites, and I have to say once I got over a few mental hurdles its been a very nice experience.

Problems?

There are quite a few things which are just done in a very different way between C# and VB.Net. Heres a quick list of the main ones that I took a while to find how to do:

  • Event Handles – in C# you just use the Object.Event += new Handler(method) etc. In VB.Net there are two methods. You either Dim the item WIthEvents and append “Handles” to the required method or use the AddHandler statement.

    Dim WithEvent form As Form
    Public Sub Form_OnLoad(ByVal sender As Object, ByVal e As EventArgs) Handles form.Load

    or

    Dim form As New Form
    AddHandler form, AddressOf Form_OnLoad

  • Types and Casting. In C# you can cast by putting brachets before the variable, e.g. int i = (int)shortVariable; Alternatively you can use the Convert.To methods to convert between the value types (e.g. int i = Convert.ToInt32(“123”)). Also there if the typeof method which returns the type of a class (e.g. typeof(Form)).

    In VB.Net the Convert.To methods have helpers methods, CStr, CInt, CLng etc, familiar to VB6 users which simply call the relevant Convert.To method. the GetType method is the equivalent of the typeof method.

    TryCast is the VB.Net equivalent of the C# “as” operator, with DirectCast and CType methods providing more general casting methods.

  • ByVal and ByRef – Even with my experience of these two parameter attributes I was never 100% sure of the difference and always just used ByVal by default. However a lot of my converted code seemed to use ByRef for no apparent reason. A bit of investigation revealed that ByRef is the equivalent of the C# “ref” attribute, except you don’t need to do anything when passing in to a method – I think this is a bad thing personally, its too easy to use ByRef without knowing why.

    VB.Net:
      Dim i As Integer
      Method1(i)
      Public Sub Method1(ByRef index As Integer)

    C#
      int i;
      Method1(ref i);
      void Method1(ref int index) {}

    I’ve also not managed to find an equivalent to the C# “out” parameter qualifier.

  • Different Names for the same thing: “MustInherit” = “abstract”, “Inheritable” = “virtual”, “NotInheritable” = “sealed”, “Shared” = “sealed”
  • Modules in VB.Net creating ‘global’ variables and methods. Generally a bad thing which as a coding purist I hate.
  • A character in C# uses the single quote marks, e.g. ‘k’. In VB.Net you append the C character to a string, e.g. “K”c – looks ugly as hell that one.
  • The auto code comment facility (three single quotes (”’)) is only turned on if generate XML documentation is also turned on – this is bad!

The Conversion Process

The conversion wizard did a very good job considering the size of the code base. The biggest issue by far is the change of arrays going from 0 to n-1 instead of 1 to n. The problem is that some code uses the new indexes and some uses the old.

  • The backward compatible “Collection” object uses the old 1 to n, where as all the nice new generics stuff uses 0 to n-1.
  • String manipulation functions like Mid, Left and Right use the old 1 to n, where as the String class methods like Substring, Remove etc use 0 to n-1.
    e.g. Mid(s, 1, 2) <==> s.Substring(0, 2)
  • Item collections, such as that of ListBox or ComboBox use the new 0 to n-1.
  • The compatability classes of TextBoxArray use the old 1 to n.

On the whole it was all just a big, very laborious nightmare, but the code conversion process does put a UPDATE_WARNING comment/task was added for almost all instances of index use that might/might not need changing.

Also, by default Option Strict is not turned on after the conversion process, in fact its turned Off explicitily in each code file, why it can’t just be set globally I don’t know.

Nice Things

Some nice things about using VB.Net are that the code compiles as you type (or rather when you save or leave a line). So you not only get the syntax highlighting you get in C# but also type checking and every other warning/error you get when compiling.

You also get the “My” namespace which contains instant access to any project resources, e.g. add a string resource call “MyStringResource” and its instantly available (with intellisense) by typing My.Resources.MyStringResource. The addition of the My namespace does add a little bit of size to your project, but once you get beyond a hello world program the difference is negligable.

In the Project Settings you get to use an “application framework” which allows you to specify a spash screen, and set various other things such as enabling Visual XP Styles, Authentication and making it a single instance application, plus automatic saving of Settings (also available via the “My” namespace).

You can set global ‘Imports’ (“using” in C#) which are imported in ever class in a project.

You can refer to other system namespaces without the word “System”, e.g. Dim stream As IO.Stream works as well as Dim stream As System.IO.Stream. I do like this one.

Not So Nice Things

The Visual Basic compiler keeps crashing. There is a hotfix which because I work for a company with Microsoft contacts I’ve got now, but without I think I would have been tearing my hair out by now. Basically about 50% of the time when you stop debugging it would crash Visual Studio.

I’m convinced that the continual compiling mentioned above slows Visual Studio down a bit. Maybe its just the size of my project :(

I’m now very used to Intellisense preselecting the most recently used item in C# – this seems like a wonderful feature now so I miss it in VB.Net

New folders do not create new Namespaces in VB.Net, and I can’t find a switch to make it do this.

If statements run all elements of an If statement if you use “Or” or “And”. e.g. the following would incremement i even if it did equal 1

    If i = 1 Or Increment(i) = 1 Then

You need to use OrElse, and AndAlso instead, the following would NOT increment i if i equalled 1:

    If i = 1 OrElse Increment(i) = 1 Then

This is particularly relevant if you are doing to usual “If a Is Nothing Or a.Count = 1 Then” which will throw a NullException if a Is Nothing.

There is no inline equivalent to ++ or –. You have to use i += 1 or i -= 1 instead.

There is no satifactory equivalent to the C#  “<expression>?true:false”. There are a number of reasons why IIF is not a good choice here. Firstly if you use IIF then both the true and the false part are evaluated, again not good in the case where you can to do the equivalant of (a==null?0:a.Count), in VB.Net IIF(a Is Nothing, 0, a.Count) would throw a NullException as a.Count is evaluated even if a Is Nothing.

Also IIF is a function whose parameters and return type are of Object – therefore you lose all type checking. There is nothing to stop you doing this: Dim f As Form = IIF(boolVal, “A string if true”, -17.5). If you turn Option Strict on it will ask you to cast the return of the IIF to type Form but thats obviously not going to help. The above just doesn’t work in C#, “Form f = (boolVal?”a string”:-176.5);” just wouldn’t compile.

Conclusion

Well, VB.Net is no longer the undiscovered country it once was to me, and I am now quite happily working in both VB.Net and C# at the same time, but I still think my personal preference is going to be C#.

Links

Language comparison

Visual Basic 2005 Expression Edition

Visual C# 2005 Express Edition

Visual Basic ‘My’ Namespace Video

[tags]microsoft, vb.net, c#, visualstudio, programming, coding, comparision[/tags]