Wednesday, October 17

Visual Studio 2005 ASP.NET F5 Debugging performance

I was experiencing a delay of about a minute between pressing F5 to start debugging my ASP.NET application (VS2005 SP1, Vista) and anything appearing in the browser.

After researching this and installing various hotfixes, nothing improved. Removing the google toolbar however seemed to make debugging return to its normal speed.

Wednesday, September 5

ASP/ASPX pages giving 404 errors

In case I need to do this in future... I have been trying to copy a web site to a new web server (Windows Server 2003) and getting very confused about why .ASP and .ASPX pages were giving 404 errors, but HTML pages were displaying correctly. The reason was "ASP.NET" and "Active Server Pages" in the Web Service Extensions directory were both set to "Prohibited".

Wednesday, August 29

The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

I was getting an error message "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel." when trying to connect to an HTTPS site using an HttpWebRequest.

As the site I was connecting to was a test site from a 3rd party known to me, but not set up correctly at their end, to bypass this check I added the following line before calling GetRequestStream on my HttpWebRequest.


ServicePointManager.ServerCertificateValidationCallback
+= new
System.Net.Security.RemoteCertificateValidationCallback
(CustomValidation);


and added the CustomValidation function as follows:


private static bool CustomValidation(object sender,
X509Certificate cert, X509Chain chain,
System.Net.Security.SslPolicyErrors error)
{
return true;
}

Tuesday, June 12

InternalsVisibleToAttribute, Unit Testing and Strong Names

I previously posted about using the InternalsVisibleTo attibute for testing with NUnit.

I've had some problems building this with a stronly named assembly. I found the following post on Kent Boogaart's blog that describes how you should change the code in your assemblyinfo.cs file as follows:

[assembly: InternalsVisibleTo("Company")]

to

[assembly: InternalsVisibleTo("Company, PublicKey=xxxxxxxxxxxxxxxx")]

Adding a strong name to a third party dll

I've been trying to build an assembly with a strong name and had some problems as it referenced a 3rd party assembly which had been built without a strong name.

To add a strong name I disassembled and reassembled the 3rd party assmbly as follows:

ildasm /out:thirdparty.dll.il thirdparty.dll

ilasm /dll /resource=thirdparty.dll.res thirdparty.dll.il /out=thirdparty.dll /key=mykey.snk

Tuesday, June 5

World Environment Day

To celebrate World Environment Day, we have all been given a flowerpot, some peat and some forget-me-not seeds. You can follow whether the seeds grow into a beautiful plant or not here.

Refreshing Progress Bars

I've been having some problems getting a progress bar to refresh, trying various calls to Refresh() and Invalidate() without much success. The solution to this is to create the dialog containing the progress bar in another thread, as described here.

Although the dialog is modeless, it should be displayed using ShowDialog(), not Show().

Wednesday, May 16

Standard for improving Standards

Simon Baker suggests that standardisation does not have to supress innovation.

It's important to communicate the best ways of doing things, but standards are often enforced in a way that people are expected to accept without question. However, there are often many ways of doing something, and the best way will change over time with changes in technology and changes in people.

Perhaps standards should be seen as something that should be followed, but when its thought they cause a problem, judgement should be used as to the correct procedure should be followed. However, if people use judgement to deviate from the standard, any differences should be noted and their effect should be considered afterwards.

The differences can then be assessed to see if deviating from the standard was the right thing with hindsight and if so, the standard should be improved. if it was the wrong thing to do, we might need to explain the rationale behind the standard better.

Monday, April 16

Visual Studio 2005 - Disappearing controls on Windows Form

My computer crashed the other day and when I returned to edit my application, to my horror I noticed that the controls on a very complicated windows form that I was working on had vanished. When I tried to edit it, all I got was an empty dialog box, but all the source code for my form was still there.

I found several references to disappearing controls in VS2003, but they all said the problem had been fixed in VS2005.

The cause of this turned out to be that some lines had removed themselves from the designer.cs file :-


///
/// formMyForm
///
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.ClientSize = new System.Drawing.Size(869, 717);
this.Controls.Add(this.splitContainer1);
this.Controls.Add(this.buttonOK);
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.buttonAccept);
this.Name = "formMyForm";
this.Text = "My form title";




Copying these lines from the version in source control seemed to restore all the controls in the dialog.

Thursday, March 1

Complete years between 2 dates

A problem we have had calculating ages was due to it using the SQL Server "DateDiff" function. This counts the number of times a day crosses a boundary, e.g.

DateDiff(year,'12/31/2006','1/1/2007') is 1, as it crosses the 2006-2007 boundary.
DateDiff(year,'1/1/2006','12/31/2006') is 0 as it doesn't cross a year boundary.

I have written a function "yeardiff", which calculates the number of complete years between 2 dates, so

YearDiff('12/31/2006','1/1/2007') is 0
YearDiff('1/1/2006','12/31/2006') is 0
YearDiff('12/31/2006','1/1/2008') is 1

This function works by calculating the number of days the start date is into the year, subtracting this from both start and end dates (so the start date is 1 January), and calling DateDiff on the resulting date.

Here's the source code for this function:


CREATE FUNCTION yeardiff
(@start as datetime, @end as datetime)
returns int
AS
BEGIN
declare @years as int

declare @daysintoyear as int
declare @firstdayofyear as datetime
declare @newstart as datetime
declare @newend as datetime

set @firstdayofyear = convert(datetime,
'1/1/'+convert(varchar,year(@start)))
set @daysintoyear =datediff(day, @start, @firstdayofyear)

set @newstart = dateadd(dd, @daysintoyear,@start)
set @newend = dateadd(dd, @daysintoyear,@end)

return datediff(year,@newstart,@newend)

END

Tuesday, February 6

Nant and licensed 3rd party controls

I've been having some problems building a project containing licensed grid and graph components from ComponentOne using NAnt. The project built correctly in Visual Studio, but when built with NAnt I got a box saying the component was not licensed.

I've found some others have had similar problems, but no solutions have been posted. I go it working after a lot of trial and error as follows:

1) Use an <exec> task to run the license compiler (lc.exe).
2) Ensure the /target: command does not contain a path.
3) Ensure your <csc> task does not contain a path in its output section.
4) Ensure the licenses file is included in the resources section. This did not work when it was included as an argument with an <arg value="/resource" element.
5) Copy the file to the correct destination directory at the end.

Here's the relevant part of my build file.


<target name="project" description="build project"
depends="..." >


<exec program="C:\Program Files\Microsoft
Visual Studio 8\SDK\v2.0\bin\LC.exe"
commandline="/target:project.exe
/complist:c:/nantcheckout/project/Properties\
licenses.licx
/outdir:c:/nantbuild /i:c:\nantbuild\C1.Data.2.dll
/i:c:\nantbuild\C1.Win.C1Chart.2.dll
/i:c:\nantbuild\C1.Win.C1Chart3D.2.dll
/i:c:\nantbuild\CAInterfaces.dll
/i:c:\nantbuild\CDERules.dll
/i:c:\nantbuild\clTreeViewHashT.dll
/i:C:\WINDOWS\Microsoft.NET\Framework\
v2.0.50727\System.configuration.dll
/i:C:\WINDOWS\Microsoft.NET\Framework\
v2.0.50727\System.Data.dll
/i:C:\WINDOWS\Microsoft.NET\Framework\
v2.0.50727\System.Deployment.dll

...

/>

<csc target="winexe"
output="PCOBrowserGE.exe" debug="false"
define="TRACE" >
<sources>
<include name="c:/nantcheckout/
project/*.cs" />
<include name="c:/nantcheckout/
project/Properties/*.cs" />
</sources>
<resources>
<include name="c:/nantcheckout/
project/Properties/*.resx" />
<include name="c:/nantcheckout/
project/*.resx" />
<include name="c:/nantbuild/
project.exe.licenses" />
</resources>
<arg value="/reference:C:\nantbuild\
c1.win.c1chart.2.dll" />
<arg value="/reference:C:\nantbuild\
c1.win.c1chart3d.2.dll" />
<arg value="/reference:C:\nantbuild\
c1.data.2.dll" />
</csc>

<copy file="pcobrowserge.exe" tofile="
c:/nantbuild/project.exe" />
</target>

10 Characteristics of a great programmer

Steve Riley has complied a great list of the 10 characteristics of a great programmer.

I'd agree with everything on the list - the one thing that is missing is that great programmers know why they are doing what they are doing - there's no point producing an excellent solution to the wrong problem.

Thursday, January 25

Cakes

Cote writes about requirements gathering and cakes.

If your powerful boss asks you for a cake, you can't easily find out the details of what he wants. You have to find out via secondary sources (e.g. the boss's calendar, asking the baker what sort of cakes the boss has ordered before). The calendar may not be up to date, and the baker may not remember accurately.

This takes longer and is more likely to go wrong. If there are more steps than necessary in finding out requirements, the solution is to understand what the difficulty is with asking him directly and work on reducing these difficulties.

Wednesday, January 24

Personal Search Filter

If you want to find out information about something, you will typically enter terms into a search engine.

The search engine will determine which results are most relevant (by using a complex algorithm based on how important it thinks the pages are). Everybody using this search engine will see the same results.

The things you want to see might not be the same as the things others want to see. However, you are more likely to want to see things that people "compatible with you" liked. If A likes B and B likes C, and B also likes D, then chances are that A will like D.

You could filter the results of your search (from the search engine) through a personal search filter. This would reorder your searches depending on

1) Things you have liked before
2) Things that people compatible with you have liked before.

When you visit a web page, you record whether you found it valuable. This updates your personal search filter and how compatible you are with other people. If you liked page A and B didn't like page A, you will not value the opinion that B liked page C. However if B liked A, you would be compatible with B and their opinion would affect your search filter.

This can be seen below:

Friday, January 12

Anti-tests

Charles Miller describes the concept of an "Anti-Test", which is a test that verifies a bug exists.

This can be written when the problem is discovered, even if it's not going to be fixed immediately.

It means that if the problem is inadvertently fixed as a result of something else, we know this has happened, have a look at why this is the case and update our records accordingly. The test can then be changed to a normal test to make sure it doesn't go wrong again.

When you're ready to fix an anti-test, you can change it to a normal test - it should now fail (and this change should be easy to make), fix the bug and make sure the test passes.

NAnt version

I've been trying to add version numbers to a NAnt build script using the <version> task, and come across a problem with the script in Marc Holmes' "Expert .NET delivery" book.

The task increments a property called "buildnumber.version", not "sys.version". Adding the following line to the script (as described here) seems to fix it.

<property name="sys.version" value="${buildnumber.version}" />