Restart regularly to avoid Last Known Good Configuration problems

Until last week I didn't really know what last known good configuration actually meant. It turns out that what it means is "I'm going to throw away all the settings you've changed since the previous start-up of this PC", which can be a bit problematic, to say the least.

We had a problem with a production server which ended up requiring a reboot. Unfortunately the server failed to restart properly and the only option left was to choose last known good configuration.

The event log shows that the uptime was over 18 million seconds - the last reboot was at the end of March, 7 months ago. In this time various services had been installed, which all vanished as the system rolled back the registry changes.

My advice would be to reboot as regularly as possible, so that if you do ever have to choose last known good configuration then you don't wipe out too many changes.

Missing (Hidden) ODBC Data Sources

Have you ever created an ODBC System DSN, only to watch as it doesn't appear in the list in the ODBC Data Source Administrator control panel? I recently used a PC (Windows XP SP2) where the registry showed that new DSNs were being successfully created, but the dialog refused to display them.

The real problem was that I was creating the DSNs for use in a Crystal report, and they weren't showing up in the list of available DSNs in the Crystal designer either.

This doesn't seem to be a very common problem, but I did eventually find evidence that other people had suffered from and fixed the same issue.

Under the HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI\ODBC Data Sources key there's a string value called (Default), which should be be empty: it will display as (value not set) in the list view:

Default shown in a list

or as a blank string if you open up the dialog to modify the data:

Default shown in a dialog

The key point here is that the data is not a blank string, and is not the text "(value no set)" which one blogger found! It must be set to the registry equivalent of NULL.

The problem can easily be recreated by clicking OK on the above dialog, rather than cancel. If you do this you'll notice that (value not set) disappears from the list view, as the empty value is replaced by a blank string:


Any new ODBC System DSNs will now fail to appear in the Administrator dialog, even though they are stored in the registry.

To fix the problem, simply delete the (Default) value. It will be instantly recreated as (value not set), and if you re-open the Administrator dialog then all of your DSNs will now be visible. They will also show up in other applications like the Crystal designer.

MobileMe and Outlook contacts: Invalid ENTRYID

Apple's MobileMe service has been through some troubled times since its launch in July, but they seem to have finally fixed a nasty problem which corrupted the Outlook address book.

Following the very first sync, Outlook contacts became unusable in emails. Hitting ctrl-k didn't autocomplete the names as you'd expect, and clicking on the To button brought up a list of names but no email addresses. Worst of all, right-clicking and requesting the properties of a contact from this list gave the following message:

 An invalid ENTRYID was passed in

 Recently a new version of the MobileMe control panel has been released, and the online support chat advice was as follows:

  • Install iTunes 8.0.1
  • Install new MobileMe control panel (this happened automatically on one of my PCs)
  • Reboot
  • Sign out of MobileMe
  • Sign back in

At this point all sync settings had been reset and the control panel showed that syncing wasn't enabled, so I would add a few extra steps:

  • Enable automatic syncing
  • Enable contacts
Control panel settings

There seemed to be some confusion about whether the computer could really have the same name as one already in use with this account:

 Computer Name Already Registered

I chose Use same name. Once this was dealt with and I hit Apply, there was a further question about how the sync should work. I selected replacing the data on the PC to get rid of all the broken ENTRYIDs (this choice only affects the first sync, not the regular merging which works in both directions):

 First Sync Alert

The Outlook contacts were then all wiped out, and the new ones now work perfectly in emails, in the To dialog, etc.

Despite all the criticism of MobileMe, the contacts sync now seems to work perfectly and, to me, will be well worth £59 a year when the perpetually-extending trial period finally ends in a few month's time.

I've never tried the calendar sync on MobileMe as I prefer the sharing functionality of Google Calendar - to sync this I use the completely awesome NuevaSync, which is totally free and highly recommended.

Free SQL Server 2008 E-Learning from Microsoft

Microsoft are offering three free SQL Server 2008 E-Learning courses:

  • What's New in Microsoft SQL Server 2008 for Database Development
  • What's New in Microsoft SQL Server 2008 for Enterprise Data Platform
  • What's New in Microsoft SQL Server 2008 for Business Intelligence
The courses are available at http://go.microsoft.com/?linkid=8731212

New MSDN SQL Server Wiki

The Volunteer Moderators and Answerers who support the Microsoft MSDN SQL Server Forums have created a new wiki to present Solutions to Common T-SQL Problems at http://code.msdn.microsoft.com/SQLExamples. At the moment mere mortals can't update the solutions but you can leave comments.

Posted 17 April 2008 11:35 AM by jonsayce | no comments
Filed under:
This type of page is not served

One of my experiments with ASP.NET MVC involves integration with a shopping cart product built in classic ASP. Up till now I've been happily relying on Cassini (the web server built into Visual Studio) but today I began testing the integration and ran into a problem. As soon as I requested an ASP page, my server reported that "This type of page is not served."

Initially I wondered whether the default MVC web.config had somehow prevented ASP pages working, but it turns out that it's nothing to do with MVC or the web.config - Cassini only works with HTML and ASPX pages - ASP pages must be served up from IIS.

Posted 13 April 2008 10:38 PM by jonsayce | no comments
Filed under:
MVC: Intercepting Controller and HandleUnknownException

One of the recent videos on ASP.NET MVC covers the Hands On Labs from Mix. Scott Hanselman runs through a lab called the CustomControllerFactory, demonstrating how to build an intercepting controller.

Having followed the lab and tried the code I was left dazed and confused, and I wasn't the only one. Life would have been easier if the code from the labs were available, but I couldn't find it anywhere.

There seem to be two sources of confusion:

  • The video doesn't mention a vital addition to the Global.asax.cs file to change the controller factory
  • HandleUnknownAction ends up handling all actions

Getting the Lab Code Working 

Add a line to Application_Start (in Global.asax.cs) to set the framework to use the InterceptingControllerFactory instead of the DefaultControllerFactory:

Global.asax.cs changes

With this line set, any controllers instanciated will be InterceptionControllers. Without it, the default controller factory is used and the interception classes will be completely ignored.


Catching Unknown Actions

Once the lab code is working, you'll soon notice that HandleUnknownAction is catching every single action.

This happens because the InterceptionController never has any actions. It's a wrapper around a controller of the type specified in the URL (the controller with actions), but the InterceptionController itself doesn't have any actions, so every action will trigger the HandleUnknownAction method.

The best way to get your head round this is to download the MVC code from CodePlex, add the project to your solution and reference it directly. It's a great way to learn more about how the MVC framework does its stuff: in our example, the ProcessRequest method of the MVCHandler object creates a controller using our custom controller factory, so ProcessRequest is working with an InterceptionController.

ProcessRequest in the MVCHandler class

When the Execute method of the InterceptionController is called, it calls InvokeAction, which checks the actions defined on the controller. InterceptionController has none, so Execute calls HandleUnknownAction and our override fires. In the video Scott uses the override to check the actionName value and decide whether or not the controller should continue.


Base Class 

If you're trying to catch only unknown actions then an alternative way is to define a base controller class, inheriting from controller, which overrides HandleUnknownAction:


Now all of your controllers can inherit from this base controller:


The controller created in ProcessRequest will now be of the type specified in the URL and will have actions defined, so HandleUnknownAction will only fire when there really is an unknown action - there is no need to filter on the actionName anymore.

Msg 7391 - OLE DB provider SQLOLEDB was unable to begin a distributed transaction

This error occurred when running queries joining to a linked server, when the linked server was upgraded from Windows 2000 Windows Server 2003 SP2.

Server: Msg 7391, Level 16, State 1, Line 1
The operation could not be performed because OLE DB provider "%ls" for linked server "%ls" was unable to begin a distributed transaction.

Some common causes of the error are described on MSDN although this second article actually provided the solution we needed.

In our case the problem turned out to be that Windows Server 2003 has DTC network access disabled by default. Turning it on is pretty straightforward but stops the SQL Server service and can require the installation media.

The Microsoft SQL Server Support Blog has a post describing DTC settings in more detail, but we found that the default setup worked once network access had been enabled.
 

Posted 01 March 2008 11:58 AM by jonsayce | no comments
Filed under:
What motivates geeks?
I recently moved a project from .NET 2.0 to .NET 3.5 and discovered that a method I had used to deserialize some JSON had become obsolete. This prompted much debate with my colleagues about why the .NET framework continues to change.

The guys I was talking to both reckon that a large part of the motivation for Microsoft to keep changing the .NET Framework is just to make money. I guess in their view of the situation, the desire for change is being driven from the top, and Scott Guthrie and co. are coming up with changes to please their financially-minded masters.

I don't buy this. I can't imagine the .NET architects sitting round a table in Redmond saying "We have been told to change things for .NET 4.0 so our users have to upgrade - can anyone think of anything we can change?"

My view of the situation is that change is being driven from the bottom: the guys who actually design and build the Framework, who are passionate about creating the best development platform they can, are constantly hoping to improve things for the millions of developers out there using .NET.

The fact that I'm struggling to adapt to a change in JSON deserialization is very frustrating, but I have no doubt that the person who took the decision to deprecate the old method and create the DataContractJsonSerializer class did so because they thought it would be better than the JavaScriptSerializer.

Obviously the money men in Microsoft would have been pleased that the JSON guru decided to improve things, as it's one microscopic part of the reason that people will upgrade to 3.5, but I firmly believe that the changes are driven by people who are engrossed in the technical side of their job, and are desperate to make .NET as good as possible.

They are, after all, just another bunch of geeks. They may be more talented and more influential than your average bunch of geeks, but they are fundamentally just another team of geeks doing their jobs. In my experience, whilst geeks want to get paid just like anyone else, what they really want is to make things work better.
Programmatically Listing SQL Servers

Using the .NET Framework there are a variety of ways you can search for available SQL Servers, but no single technique does the whole job. The best approach is to use a combination of methods to ensure you get the most complete list possible.

Most methods rely on a UDP broadcast to locate servers - this is good for finding unknown servers which haven't been registered but doesn't guarantee to return the definitive list. Timeouts and firewalls blocking the relevant ports can lead to servers missing from the list and, if you're not on a network then even local servers will disappear from the list, as the UDP broadcast fails completely. In addition the list of servers is not guaranteed to be the same if you run the search twice.

The main alternative is to search the registry for registered SQL Servers. Whilst this is fine for servers you know about (and works when the network is unavailable) it doesn't allow you to discover new SQL Servers.


Method 1: UDP Broadcast

Used by:

The first two actually are actually the same under the covers: EnumAvailableSqlServers is simply an abstraction of the SqlDataSourceEnumerator class.

EnumAvailableSqlServers example

Pros:
+ Includes SQL Servers which are not registered

Cons:
- Doesn't work when there's no network connection
- Subject to firewall rules (Blocked TCP 1433 and UDP 1434)
- Doesn't find SQL Servers if SQL Browser is off
- Doesn't find SQL Servers if they are hidden
- List contents not guaranteed to be repeatable


Method 2: Reading Registered Servers from the Registry

Used by:
Microsoft.SqlServer.Management.Smo.SmoApplication.SqlServerRegistrations.RegisteredServers

RegisteredServers example

Pros:
+ Works with no network connection
+ Works regardless of firewalls
+ Shows all registered servers, regardless of SQL Browser/hidden status

Cons:
- Only shows SQL Servers which have been registered
- Will be removed in a future version of SQL Server according to MSDN


Method 3: SMO WMI

Windows Management Instrumentation provides a third way to locate SQL Servers.

WMI example

Pros:
+ Works with no network connection

Cons:
- Only lists SQL Server 2005 and later
- Only finds registered servers


Putting the methods together

If you're after a list which matches that shown in SSMS (or Enterprise Manager) then looking for registered servers will probably be an acceptable solution. If, on the other hand, you want to show all available SQL Servers (as in the SSMS "Browse for Servers" dialog), then your best bet is probably to combine one of the UDP methods with a list of registered servers. This will give you a reliable list of registered servers even when the network is down, and will include unregistered servers where possible.

One of the most user-friendly ways of doing this is to initially populate your control with the registered servers (which can be done very quickly) but allow the user to initiate a search for further network servers (which can take several seconds) in case they're looking for an unregistered server. You should always allow the user to type in a server name too, as the server may be available even though it's not returned by the UDP methods described above.

 
And another thing...

Depending on your requirements, you may need to include the instance names in the list. The methods I've mentioned all return instance names of the non-default instances (e.g. MyPC\SQLEXPRESS) but they handle them in different ways - the MSDN documentation gives full details.

More Posts Next page »