Archive for the 'Programming' Category

External graphics in XSL:FO not sizing correctly

Wednesday, June 4th, 2008

I’m using Apache FOP to generate PDFs from XSL:FO, and an external graphic (think the <img> tag in HTML) kept being resized incorrectly. Another image (different size) was the correct size on the page. Turns out I was using height and width attributes in the fo:external-graphic element, when I should have been using content-height and content-width. Somehow the second image respected the height and width I wanted. Possibly this has something to do with the stored DPI of the images (since XSL:FO is a specification for printed documents), but in any case content-width and content-height is the way to go. Way to go, Ben :P

ZedGraph - .NET graph control

Friday, March 28th, 2008

Today I needed a graphing control, and with a bit of searching found ZedGraph. This has got to be the best open source .NET component I’ve ever used. All you need to do is reference the .DLL, drop a ZedGraph control onto your form or control, and add some code to load in a data range. It’s even easier to make a pie chart and the colours, gradients, etc., are all customisable. Out of the box the control automatically has zooming, scaling, printing and exporting features accessible to the user, and it looks nice and clean. There’s also a ZedGraphWeb control built in which is for use in ASP.NET apps (although I haven’t tried that out).

There are two concurrent versions for both .NET 1.1 and .NET 2 (which is very handy since I’m limited to .NET 1.1 at work). The only difference between the versions is apparently use of templates for collections.

There’s a CodeProject article that gives a pile of simple demo code, and the main site is a Wiki with what looks like plenty of documentation. The library is licensed under the LGPL license, which means that derivative works must be LGPLed, but as long as the library’s DLLs are dynamically linked they can be included in commercial software.

Editing past log comments in Subversion

Tuesday, March 18th, 2008

Subversion is my source version control software of choice, but it’s not immediately obvious how to edit the log comment of a past commit (such as after adding a particularly scathing remark that may not be a wise career move). A caveat is that you need to have administrator access to the Subversion repository.

In the repository directory (wherever you created the repository) is a hooks folder (on my system this is H:\IT\svnrepos\pas\hooks). This folder contains scripts that are called by Subversion when various events occur (hooks). The files that are created in a repository’s hooks folder by default are templates of hooks designed for Linux etc. On a Windows server they need to be created as batch files (*.bat) to be executed.

What you need to do is create a hook that will run prior to changing a revision property (such as a log comment) and let Subversion know that changing the comment is permitted. By default changing the log comment is disabled (obviously, or you wouldn’t be reading this). Make a new file in the hooks folder called pre-revprop-change.bat and write the following into it:

if "%4" == "svn:log" exit 0

echo Property '%4' cannot be changed >&2
exit 1

The %4 argument contains which operation is being performed. If the operation is svn:log we indicate success, which is a return code of 0. Otherwise it prints an error and exits with a non-zero, which indicates an error (and that the operation shouldn’t be allowed). Once that is saved, you should be able to use your to Subversion client to edit the comment. Be careful with what you do, as revision properties aren’t versioned, and you won’t be able to undo your changes. You should also probably rename pre-revprop-change.bat to pre-revprop-change.bat.bak once finished.

Logical XOR operator in C#

Tuesday, March 4th, 2008

For reference the logical XOR operator in C# is the same as the bitwise XOR operator: ^. This always gets me because usually the logical boolean operators are like && and || versus the bitwise operators (& and |). I guess it’s the same thing anyway, just a bitwise XOR operation on two booleans. Fascinating.

Could not find resources exception when modifying a form class in Visual Studio .NET 2003

Thursday, February 21st, 2008

I changed the name of a form class and added a new class at the top of the class file with the same name of the old form class, descending from the renamed class to avoid breaking old code. Then when I ran the app I got an exception saying that the form’s resources couldn’t be loaded. When I had a look at the resources file for the form (<project folder>\obj\Debug) a resources file was still being created for the old class name instead of the new one. Since this resources file is the one that gets linked into the DLL or exe, this meant that the new form class couldn’t find its resources. According to Microsoft KB318603 this is because other class definitions located before the form class definition will be picked up when naming the resources file. So if this happens, move the other class to after the form class (ie the MyForm.cs file should contain first the MyForm class then any other classes).

Of course the best thing would be to move the other classes into another file but that sounds like work :-)

Cookies not being sent back to the server

Saturday, January 26th, 2008

I’ve been playing with CakePHP, which is an MVC framework for PHP (the PHP equivalent of Ruby on Rails) and had this annoying bug where the session cookie (which holds a session hash) gets regenerated with every page request. This had the effect that, when I saved my User object in the session after validating the login, the cookie’s value would change to a new hash (losing the auth data), meaning that the logged in status was lost when requesting a new page.

I knew that the session was getting the user data inserted, because I could see the sessions and data being created on each request. I also knew that the browser was receiving the cookie with the last generated session hash. So, since CakePHP generates a new session for each request that isn’t accompanied by a session cookie, I figured that my browser wasn’t sending the session cookie with the request.

Point 1: if you can’t make your session stick, see if you’re getting a different session hash each request, because maybe the server just isn’t receiving the cookie.

Then I tried to figure out why cookies weren’t being sent. It turns out that having a space in the url of a website (which gets converted to %20, as in http://localhost/Internal%20Projects/CakeTest) stops cookies from being sent. This may have something to do with the web server (Apache 2.2.26) or the fact that I’m using a preconfigured WampServer Apache-MySQL-PHP stack, but it is common to both Firefox 2 and IE7. Which brings me to…

Point 2: don’t put spaces in your development server’s folder names when using cookies.

Fine-tuning polymorphism in C# using the new keyword

Wednesday, August 8th, 2007

This doesn’t come up too often but can be useful. Sometimes, when using inheritance, it can be difficult to get the right implementation of a virtual method called. This is the kind of model I had today:

namespace InheritanceTest
{

	public class BaseClass
	{
		public BaseClass() {}

		public virtual void A(int count)
		{
			for (int i = 0; i < count; i++)
				B(string.Format("{0} Base Hello", i));	// This calls DerivedClass.B(string)
		}

		public virtual void B(string s)
		{
			Console.WriteLine("Base: "+s);
		}
	}

	public class DerivedClass : BaseClass
	{
		public DerivedClass() : base() {}

		public override void A(int count)
		{
			base.A(count);	// call BaseClass.A(int)
		}

		public override void B(string s)
		{
			Console.WriteLine("Derived: "+s);
		}
	}

	class MainClass
	{
		public static void Main(string[] args)
		{
			Console.WriteLine("Test begins:");

			DerivedClass obj = new DerivedClass();
			//obj.B(10);

			Console.WriteLine("Test ends.");
		}
	}
}

When this is compiled and run, the method called in BaseClass.A() is DerivedClass’s implementation of B(). The series of method calls will look like this:

  1. DerivedClass.A()
  2. BaseClass.A()
  3. DerivedClass.B() ten times

So when BaseClass.A() makes the call to B(), the derived class’s B() method is found and executed, rather than BaseClass.B(). This is exactly how you would usually want the inheritance to work; the derived class has methods that override the base class, and the base class calls fall through to the child’s implementation of the virtual methods.

The problem with this is if you want to be able to use the base class’s implementation of B() in BaseClass.A()’s call to B(). BaseClass.B()’s implementation may contain code required in BaseClass, but DerivedClass.B()’s implementation is not appropriate for use in BaseClass. Basically you want the following series of method calls:

  1. DerivedClass.A()
  2. BaseClass.A()
  3. BaseClass.B() ten times

We need to indicate to the compiler that, although DerivedClass.B() implements B(), it doesn’t necessarily override BaseClass’s implementation of B(). That is done by changing the override keyword in DerivedClass.B()’s declaration to new:

Change:
   public override void B(string s)
to:
   public new void B(string s)

The effect of this is that when B() is called in BaseClass, it will be BaseClass.B() that will be executed, because DerivedClass.B() is flagged as a new implementation of the B() method that does not override the existing one. The new DerivedClass.B() method is still visible in DerivedClass and beyond:

DerivedClass obj = new DerivedClass();
obj.B("Test");   // This will execute DerivedClass.B(), not BaseClass.B()

will execute DerivedClass.B().

Security error when impersonating a user in an ASP.NET application

Thursday, July 12th, 2007

I was trying to get security impersonation working in an ASP.NET app so that database access would work correctly. For reference, to impersonate a user, add this to the web.config file:

The password is stored in plain text format, this is a bit scary but that looks like the way to do it. There must also be a way of using IIS to do the impersonation but I couldn’t get that up.

Now that the app is impersonating the MyDatabaseUser account, it no longer has access rights to the temporary ASP.NET folder. This gives a yellow screen of death with the following error:

Access to the path "C:\\Windows\\Microsoft.NET\\Framework\\v1.1.4322\\Temporary ASP.NET Files\\MyApplication\\XXXX\\XXXX\\hash.web" is denied.

To resolve this, the account needs to be given write permission to the temporary folder. Browse to "C:\[windows]\Microsoft.NET\Framework\[.net version]", open properties for the Temporary ASP.NET Files folder and go the Security tab. Add your database user account and give it the same permissions as the NETWORK SERVICE user (full control). Once this is applied the user (and therefore the application) will have access to the temporary folder root. Now you can move on to the next YSOD.

Aussie Tender Centre website touchup

Friday, July 6th, 2007

I’ve just finished up some changes to a site I developed about four years ago - the Aussie Tender Centre. This was the first commercial site I ever worked on, and it’s been running almost constantly, with very few issues and quite a bit of traffic. Check out the Virtual Tour link on the top menu bar - David (the manager) gives me a little plug :-D

Six ways to write more comprehensible code

Thursday, May 31st, 2007

Slashdot has linked to an article Jeff Vogel has written on developerWorks called Six ways to write more comprehensible code. It’s focused on C+ and uses variable names with underscores and global #DEFINEs etc that I personally hate, but the ideas are spot on.