Thursday, March 29, 2007

OTA Bitmap Format

Further to the post about embedding a bitmap into an SMS, I needed to know the format of the picture to send. Wikipedia has an excellent article on the format, so I'll need to use this when I get those 5 minutes to give it a go.

Picture Messages in SMS

Embedding a bitmap picture into an SMS isn't something that Esendex directly supports, but after a customer's request I thought I'd take a few minutes to find out how to do it.

So I sent a picture message from my phone into one of our virtual mobile numbers, and I'm pretty sure I can reverse engineer the bytes that I got.

Then I found this Nokia article on it, which I should have known already as I used to have this document on my desk pretty much all the time... So it looks quite interesting.

I'll give it a go when I get 5 minutes, but the specification doesn't seem that complicated. Watch this space I guess.

Wednesday, March 28, 2007

MailMessage Subject Property Error

Just a small problem this time for the .Net 2.0 Migration. Assigning a string that contains line feed characters to the Subject property on a System.Net.MailMessage object will result in an error being thrown that says:

The specified string is not in the form required for a subject.

Just make sure you strip out any carriage returns (\r) or line feeds (\n) from your string before you assign it and everything will be fine.

So done, onto the next one...

EventType clr20r3 From Windows Service

In the final throws of testing part of our system on the new .Net 2.0 code, we deployed a few of our Windows services to a production server in preparation for going live with it. Luckily for us that we did because we found that one of the services appeared to stop occasionally.

The service is responsible for notifying our customer's applications of events on their accounts as part of our Push SMS API service, which for many customers is a very important part of the services we offer. So we needed to get this problem fixed before going live, but we had a number of problems with finding out why the service was stopping.

We use log4net for logging within all of our applications, but these log files did not show any errors being thrown from the service.

However, the Event Viewer did trap an error. It was in the category of a .Net Runtime 2.0 Error, being logged in the Application section of the Event Viewer. The error message looked like this:

EventType clr20r3, P1 t1f44vcumbpfz21uvtobhdijm4egyfae, P2 1.0.2643.18660, P3 460a41c8, P4 mscorlib, P5, P6 4333ab80, P7 4052, P8 27, P9 qvnotafqzyql5inknkn5msslsene3ln1, P10 NIL.

I think you'll agree its not that much help. Most of the errors were the same, but some had different garbled text in the P9 section.

The code that was running hadn't changed since the 1.1 build, and the service never used to stop on any errors previously. We have error handling that will log any error and allow the service to carry on in the event of any failures. Or so we thought anyway.

I was maybe 5 minutes away from raising a support call with Microsoft, when I found this article that explained how I could make the error message more useful: Tech Notes :: DotNet Runtime Error UPDATE: Original link seems to have died. See below.

The error is an example of an unhandled exception being thrown out of the application. You can make some sense of the error by implementing a handler for the UnhandledException event on the current AppDomain that your application is running in. This event will pass in the exception object that has been thrown, so you can log it to the Event Viewer in a more meaningful fashion.

From this we found the error and have now corrected it so the service doesn't keep stopping.

When the service started it would perform each task it was required to do in a method that we had queued in the ThreadPool. If this method managed to throw out an exception, then of course that current Thread would exit. Now, we shouldn't have been throwing exceptions out of this method anyway, but the 1.1 Framework didn't seem to mind about it.

In the 2.0 Framework it seems that if a method that is in the ThreadPool throws, then that Exception takes down the application, in this case the Windows service. Personally I feel that this is a better way of doing it, as the 1.1 Framework was masking an error in our code. The error message could have been a bit more meaningful in the first place though.

UPDATE (3 Apr 2009): The original link that was the inspiration behind solving this no longer exists.  However if you are interested please check out Unhandled Exception Processing In The CLR from the MSDN Magazine for more information.

Tuesday, March 27, 2007

DateTime XML Serialisation in .NET

Got quite a few posts to write about more version 1.1 to 2.0 migration issues. We've recently released the .Net 2 build onto some of our servers for testing, and there were quite a few problems. I'll try to keep 1 post per issue we saw.

We had a problem with our scheduled SMS service (which allows customers to specify a date and time when they want to submit a given SMS), in that the dates being used weren't being respected correctly when posting from a .Net 2 web service, through an XML formatted MSMQ, and being processed by a .Net 1.1 Windows service.

This was due to the differences between how the versions serialise DateTime objects to XML. There is what I would call a bug in the 1.1 framework that means you cannot serialise a DateTime that represents a UTC time (i.e. with zero offset from GMT, and no daylight savings adjustments). Check out this very useful article about DateTimes in general: Coding Best Practices Using DateTime in the .NET Framework.

It seems any time you put in is treated like the local time for the application deserialising it. I'm not entirely sure, but if you indicate that the time is in UTC (by adding a Z to the end of the time section), the 1.1 framework does treat that as UTC (Zulu) time, but then internally corrects it to the local time the server is in. That's certainly the behaviour we observed during tests anyway.

This has been fixed in version 2, so our solution to the problem just involves altering the order in which we deployed the .Net 2 builds to our servers.

Tuesday, March 20, 2007

ASP.Net 2 Control Client Names with Dollars not Colons

Currently migrating a lot of .Net 1.1 code to .Net 2, and was having problems with one particular ASP.Net page. This page uses a custom control that we have written to display one of our objects. It is a composite control that displays a number of text boxes, check boxes and the like, to represent the object passed in to it.

Well this control pulls form variables during the post back, and updates the underlying object with what the user has entered. The problem was that on a Windows XP development PC this all worked fine, but during a test deploy onto a Windows 2003 server the page didn't save the updated values.

The names of the controls had all been separated with a colon (:) on the development PC, and a dollar ($) on the server. This was a problem as the custom control was set up to separate the names using the colon, which had always worked in the past.

The answer came from a forum posting.

On the development PC the Web.config file had the setting

<xhtmlConformance mode="Legacy"/>

in the system.web section, but the server did not.

Monday, March 19, 2007

Gacutil.exe in .Net 2

Deploying a .Net 2 application onto a test server that doesn't have the SDK (but does have the framework, of course), we have a script that installs a bunch of assemblies to the GAC. This script uses the Gacutil.exe program, found in the C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322 folder in .Net 1.1.

Problem with this? Gacutil.exe doesn't ship with the framework any more, only with the SDK. Apparently the recommended way of deploying is now with a Setup and Deployment project from Visual Studio 2005.

Well we can't do this, so I've copied Gacutil.exe, and Gacutil.exe.config to the framework directory on the server, and hey presto, the scripts now install the assemblies correctly.

Thursday, March 15, 2007

Web Service Enhancements 3.0

For the last couple of days I've been attempting to communicate with an external Web Service that I need to use Web Service Enhancements for. Particularly I needed to set the value of a UsernameToken within the header.

I found a codeproject article on it (WS-Security: Secure Web services through SOAP Message Level Security) on which I based the code, and this did work. I eventually got successful responses when I had figured out the right format of parameter to use.

However, the codeproject article was written for WSE 2.0, and I was using WSE 3.0. The Security property on RequestSoapContext is rather annoyingly marked as Obsolete in WSE 3.0, and I was using this to set the required header.

Eventually I found the rather snappily titled article Custom WSE 3.0 Policy Assertions for Signing and Encrypting SOAP Messages with Username Tokens on codeproject again. From this I found I had to replace my 1 line of client code with 2 separate classes, and 4 additional lines within the client code.

I have no idea why the propery is now Obsolete, but the new way of doing the same thing was much too difficult to find in my opinion.

Wednesday, March 14, 2007

.Net 2 Upgrade causing COM+ problems

I've been using .Net 1.1 since leaving university just over 3 years ago now, but over the last couple of weeks we've been updating to .Net 2. It's not proven to be an easy transition, and not only because of the updated web application format that Visual Studio 2005 now uses.

When our build got to our SMS XML Web Service APIs we had a lot of these errors:

The requested operation requires that the current context have a Transaction, and it does not.

The APIs use COM+ as a business logic layer, and initially it seemed to only be a problem when we had a ServicedComponent calling a non-ServicedComponent which in turn called a different ServicedComponent. However, we refactored some code around to remove the middle section, and the error still threw.

A Google search for the error doesn't find that many pages, but luckily there is a knowledge base article on it. There is also even a patch for it, but only for Windows 2003 Server editions, and (like most people) we don't actually develop on a server operating system.

There is no hotfix for Windows XP Professional, and no usable workaround for that OS was listed either. As a last ditch effort we attempted the registry fix workaround listed on that page, which is to add a new key string value for DisablePromotableTransactions in HKEY_LOCAL_MACHINE\Software\COM3, and set the value to Y.

But look in the registry on a WinXP box and you'll find that the required registry location doesn't exist. There is however a HKEY_LOCAL_MACHINE\Software\Microsoft\COM3. Not knowing whether it would work, we just tried putting the entry there instead.

And it worked. The tests passed and the build continued. No more COM+ problems after that.

But it does raise the question of what else that registry key is controlling. The research that we've done on it seems to suggest promotable transactions are a new feature of Sql Server 2005. As we aren't using that in either production or development we're probably ok. Also, it's only a problem on our development machines, as production boxes do have the hotfix applied.