Thursday, March 06, 2008

That's All Folks

Today marks the end of an era for me. After more than 4 years at Esendex I feel that now is a good time to move on to pastures new. It's my last day today, and this will be the last post of this blog as well.

I first set this up to chart the experiences and knowledge gained during my work at Esendex, and now that work has come to an end I feel it is also fitting that this blog should as well.

I shall keep blogging though. I recently remembered that way back in 2004 I reserved iandykes.blogspot.com so I've resurrected that one and intend to keep it updated from now on.

Monday, February 25, 2008

Cool CG Animated Short Film

A CG 3D animated short film, apparently created by just one person. Amazing level of detail, and raised a few smiles as well. Looks very polished and professional.

Friday, February 22, 2008

A Brief Introduction to REST

If you're looking for information on REpresentational State Transfer, then check out A Brief Introduction to REST at InfoQ. I particularly like:

The next principle we’re going to look at has a formal description that is a little intimidating: “Hypermedia as the engine of application state”, sometimes abbreviated as HATEOAS. (Seriously — I’m not making this up.)

Thursday, February 21, 2008

Assigning Basic Authorization HTTP Header to HttpWebRequest







If you're making a call to a HTTP resource that requires a Basic Authorization HTTP header, you can use the following code:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("url-here");
request.Credentials = new NetworkCredential("username", "password");


Then post the request in the usual way.

The confusion comes because on the first call the HTTP header will not be present on the request. The framework is relying on the first call receiving a 401 response, with a WWW-Authenticate header present, giving a Basic realm=<realm-name> value. A second call will then be made with the correct headers in place.

If you are just consuming the resource, chances are the server will respond in a way that allows this behaviour. However, if it doesn't respond with a 401, or that 401 response doesn't contain the WWW-Authenticate header (or you just don't want to make 2 calls), then you have to manually add the Authorization header to the request:

byte[] authBytes = Encoding.UTF8.GetBytes("user:password".ToCharArray());
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(authBytes);

Wednesday, February 20, 2008

Writing XML with UTF-8 Encoding using XmlTextWriter and StringWriter







If you want to use XmlTextWriter to write XML into a StringBuilder you can create the XmlTextWriter like this:

StringBuilder builder = new StringBuilder();
XmlWriter writer = new XmlTextWriter(new StringWriter(builder));


But this generates a declaration on the resulting XML with the encoding of UTF-16 (the encoding of a .Net String). There doesn't seem to be a straightforward way of making this declaration UTF-8 in this set up.

You can, of course, use a MemoryStream instead of a StringWriter, and then use Encoding.UTF8.GetString(...) to convert the bytes to a string, but doing this made the resulting string have non-printable characters in it, which we don't want.

The solution is to subclass StringWriter and override the Encoding property. Sounds a bit overkill for a solution, but it works very well. Just create the following class (based on Jon Skeet's class):

public class StringWriterWithEncoding : StringWriter
{
Encoding encoding;

public StringWriterWithEncoding (StringBuilder builder, Encoding encoding)
:base(builder)
{
this.encoding = encoding;
}

public override Encoding Encoding
{
get { return encoding; }
}
}

Then use StringWriterWithEncoding instead of StringWriter in your XmlTextWriter.

This operation requires IIS integrated pipeline mode







If you're getting an error message

This operation requires IIS integrated pipeline mode

when trying to add headers to a HttpResponse object in an ASP.Net web application, chances are you're trying something like this:

response.Headers["myHeader"] = "someValue";

or

response.Headers.Add("myHeader", "someValue");

A quick Google reveals mentions of bugs in the 3.5 framework, but I'm using .Net 2. Nevertheless you can work around this problem by adding your header this way instead:

response.AddHeader("myHeader", "someValue");

And your code should now add the header successfully.

Monday, February 11, 2008

50 Open Source Alternatives to Proprietary Programs

The Top 50 Proprietary Programs that Drive You Crazy — and Their Open Source Alternatives

Decent list of open source software for pretty much anything you want to do on your computer.

Tuesday, February 05, 2008

Custom ThreadPool

Last year in a post from the last day at Tech Ed I mentioned a talk about building Scalable ASP.NET Web Applications, in which a warning was given about using the normal .Net ThreadPool in web apps. A suggestion was made to instead use a custom thread pool so that ASP.NET's worker threads weren't all used up.

In that talk it was said there was code for such a class on the Wintellect website, but I remember looking at the time and couldn't find anything.

I've since found Mike Woodring's .NET Sample Page, on which there is a custom thread pool inplementation available for download.

I've not needed to use it yet, so can't comment on its usage, but I'll give it a go when I need control over the ThreadPool.

Wednesday, January 30, 2008

Get the current date as a string from a batch file

Ever needed to include the current date in something like a filename from a batch file? Check out this MS KB article on how to do it.

I've changed the format slightly to include a dash between each part. This is what I used:

SET current.date=%date:~-4,4%-%date:~-7,2%-%date:~0,2%

Friday, January 25, 2008

Mario, Lego, Plasticine, and Friday afternoon equals...

Nice to see Jonathan and Kevin have been hard at work this Friday afternoon... ;)



read more | digg story

Monday, January 21, 2008

Truth About Xbox 360 Red Ring of Death

Interesting interview with a "Microsoft insider" covering the Truth About Xbox 360 Red Ring of Death.

Not sure how reliable the source is, but it makes interesting reading.

Wednesday, January 16, 2008

Force a C# Web Service Proxy to use HTTP 1.0






(Code at the bottom)

Esendex customers can submit SMS using .Net Web Services. While the simple code samples we provide will get most people up and running, the samples aren't always enough when volumes start to increase.

The most common error report we receive from these high usage customers usually contains a complaint that our APIs are down, and aren't responding, but this is rarely the case. Our server array offers all our customers the responsiveness and the reliability that they will need, but the error report always seems to look like this is the case.

Normally the problem is at the customers side, and more often than not it's due to them consuming our Web Services using HTTP 1.1.

A limitation of HTTP 1.1 is that it only support 2 simultaneous connections to another server. This is usually OK, but if a customer has a multi-threaded application then this can quickly become a problem. The problem manifests itself with an error that looks like the server is down.

In reality what you'll have is a bunch of threads all waiting for a chance to connect, and when they don't you tend to get timeout errors that make it look like the server didn't respond.

To get around this you need to connect using HTTP 1.0, but by default Visual Studio creates a web reference using 1.1. So you need to do some tweaking.

Basically we need to override the GetWebRequest method on our generated web reference and alter the properties on the HttpWebRequest so that we can assign the right version.

When you add a Web Reference in Visual Studio you effectively add an auto generated class to your project, which (if you look down the directory tree in Windows Explorer) is saved in a Reference.cs file. This file changes every time you tell Visual Studio to update the web reference.

Because of this it isn't always possible to override that particular class. If you working with an API that can change and you want to be able to update it easily, then you'll have to use partial classes in order to override the method. Or you could sub class the proxy and override it in there.

Personally I like to move the Reference.cs file into the project as a normal file (renamed of course), and then edit the generated code. I can do this as I know that the API isn't going to change (if we do need to offer new functionality we release new Web Services rather than change existing ones).

This allows you to override the method in the normal way, and also allows you to change how the proxy gets the URL to connect to.

Whichever way you do it, here's the code you need to add in:
protected override WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest request =
(HttpWebRequest)base.GetWebRequest(uri);
request.ProtocolVersion = System.Net.HttpVersion.Version10;

return request;
}
And, as you've now got access to the HttpWebRequest you can also disable Keep Alives if they're causing you problems as well.

Sunday, January 13, 2008

confused.com? You will be...

My car insurance is due this month, leaving me with that magical four years no claims that most insurance companies seem to love. So I went to confused.com to give it a go.

I used my iPod Touch as I didn't want to boot the laptop, and maybe this contributed to the frustrating experience, but if a website can't support Safari then that's hardly my problem really.

It didn't start well as the Get Quotes button was floating at the bottom of the page rather than in line with everything else, but it was about to get worse. The site didn't recognise my registration number so I had to manually enter my car details. This is the first site that has failed to find my car from the number plate, and I've used a number of them for looking for insurance and tyres before.

Then I was asked for my occupation, and although it didn't recognise Software Developer it did seem to pick up Programmer. Well, it was listed as Computer Programmer in the list so I selected that and tried to continue. That was no good for it though, I had to type in my occupation so that it matched what I selected in the drop down list. Further frustrations...

Eventually I get to the last screen on which I'm asked to enter a password so I can retrieve my details later. So I enter a password only to be told it isn't good enough. Passwords have to be between 6 and 8 characters apparently...

So I entered in a password that matched this criteria only to be told it still wasn't good enough. I gave up at that point, as a user of web applications I expect better.

As a developer of web applications I know the whole experience can be much better.

What's the point of heavily advertising your service if you confuse your would be customers before you've convinced them to part with any money?

So, after being thoroughly disappointed with that experience I'm just going to stay with my current insurer.

Friday, January 11, 2008

What skills should a graduate have?

There's a question What Skills Should Undergrads Have running on slashdot from the aftermath of the whole "Java is damaging students" article. There's a lot of answers already but I think one of the important ones is being able to visualise how software connects to each other.

As a graduate programmer it's highly unlikely that you will be given a green field development project. It's more likely that you'll be maintaining or enhancing an existing system, so it's important to be able to see in your mind how and where the different components connect.

I've tried to answer questions like this before, but it's so difficult as a professional developer needs to have so many skills it's impossible to narrow down even a few as being the most important. But I guess when you're starting out in the business you need to:

  • Realise that you don't know anything
  • Be willing to learn
  • Not be afraid to ask questions
  • Be able to analyse problems and visualise solutions
Technical ability is of course important, but you need to interview well and show some potential to get a decent job out of it.

A friend of a friend I met in sixth form college once claimed that he didn't need any computing qualifications to get a job, as his proven ability at writing his own programs would set him apart from everyone else. And admittedly he had written a lot of programs.

Yet from an employer's point of view all that work he's done hasn't been in a commercial environment where change requests are common, priorities change, your projects are moved to other developers, and you're asked to work on projects of which you have no knowledge.

The experience he had of writing programs didn't cover any of that, and being flexible enough to handle those situations is a very desirable attribute to employers.

I don't know what he's doing now. Maybe he's carrying on doing what he wants and making a living out of it. But even if that worked for him it's certainly not a path I would recommend for people wishing to get a foothold in the industry.

Thursday, January 10, 2008

Needle in a haystack

Been a bit quiet on the blogging front recently. That's mainly because I'm currently running through some tests for the first iteration of an update that will drastically change the architecture of the Esendex Messaging System. I can't go into detail about the change, but my current tests run into a very intermittent failure.

At irregular intervals one of the services hangs: just totally stops responding, and because it's multithreaded the log files aren't much help. Actually, its worse than looking for a needle in a haystack, as at least in that case you know what you're looking for.

It first presented itself after sending only 100 messages, then after 2,000. An initial investigation didn't shine any light on anything so I sent some more messages. It hasn't failed again yet, and I've currently sent 15,000 through. No code change either, so the error is still in there waiting to be found.

Frustrating is not the word.

Thursday, January 03, 2008

Esendex Webservice SMS using C++

C++ is not my main language, but all Esendex developers are expected to help our customers integrate their systems with ours on top of our usual development work.

Admittedly we don't have many people asking for help with C++, but when they do we usually direct them to the C++ SMS SDK. This includes a COM component which developers must install, and this fact does pose some problems for some developers.

So, while waiting for a build I found How to Consume [a] WebService via unmanaged C++, which describes how you can get Visual Studio 2005 (and apparently 2003 as well, but I've not checked that), to generate a proxy for you.

In Visual Studio 2005:

1. Generate the proxy:

  1. Right click on the project in the Solution Explorer and click Add Web Reference.
  2. In the dialog, enter http://www.esendex.com/secure/messenger/soap/SendServiceNoHeader.asmx as the URL, and give it a name
  3. Click Add Web Reference
  4. This will generate a file in your project (with the name you gave it)
2. Write code to call the proxy:

SendServiceNoHeader::CSendServiceNoHeader proxy;
BSTR result = NULL;
HRESULT hr = proxy.SendMessageFull( CComBSTR("username"),
CComBSTR("password"),
CComBSTR("account reference"),
CComBSTR("originator"),
CComBSTR("destination"),
CComBSTR("C++ Hello!"),
CComBSTR("Text"), 0, &result);
3. Notes:
  1. result will contain the ID of the message you've just sent
  2. hr can be used to check if the operation was successful
  3. You may need to include the line CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); before this code if your application doesn't already have it.