Jan Schreuder on .Net

.Net code samples, experiences, observations

View my professional profile on LinkedIn

Recent Posts

Tags

News

  • Inappropriate comments will be deleted at my discretion.

    The information and code samples in this weblog is provided "AS IS" without warranty of any kind, either expressed or implied, including but not limited to the merchantability and/or fitness for a particular purpose.

Community

Email Notifications

Tool suppliers

Tools

General

Microsoft

Favorite blogs

Archives

July 2005 - Posts

The art of software development

I've been having these thoughts lately, and a recent discussion with a friend of mine made me want to write it all down. So I've written an article on software development as I see it. There's probably a lot of familiar stuff in there, but I needed to get it of my chest. Feel free to comment!

Link to the article...

Windows Vista, the continueing story...

By naming the next version of Windows "Vista," Microsoft may have stepped on the toes of another software company just down the road in Redmond. that would be Vista, who build software for small businesses. Full story here

Commercial name for Longhorn will be Windows Vista is now Official

Various sources in the internet claim that Longhorn will be named Windows Vista:

Apparently this was reveiled at a Microsoft staffconference in Atlanta, USA yesterday. According to this link, Microsoft has already registered the domain WindowsVista.US somewhere in April.

Official statement from Microsoft

 

Code Complexity

A few months back, I tried to make a case for code inspections. So I was happy to find the following post on Michael Swanson's Blog at MSDN.

Michael Swanson helped manage the development team for NxOpinion diagnostic software. NxOpinion is a medical decision-support application. The team used some techniques from Agile, but also implemented formal code reviews and code metrics. During development, pair-programming (one writing code, one reviewing the code as it is written) was used. But they also held formal code reviews. They did this to educate people about the coding standards that had been agreed upon and to focus on improving the functionality of the code.

On a daily basis, an automated process would check out all the code and calculate the metrics. These metrics were stored as checkpoints. They were also used to pinpoint which code was a suitable candidate for code reviews. The higher the complexity of the code, the more likely it would be a candidate for a review.

A definite read if you're interested in code reviews!

In the comments on this post, you will find links to various (freeware) code complexity tools. I can recommend the community version of DevMetrics. I'm using it in my current project to pinpoint candidates for review and/or refactoring.

How to: Make a text fit your labels

I've had this problem before, and I just ran into it again: The text I'm trying to add to a label is too long and now the text spans more than one line and it doesn't fit anymore...

In my situations, I could very well live with having this text truncated to something that would fit. I can add the entire text to a tooltip, so that it will show when the user hovers the label. I created some code to do this in a generic way. First, I had to figure out how wide the text was. That can be done using the MeasureString method from the Graphics method:

private static int PixelLength(string text, Font thisFont)
{
    Label    lbl = new Label();           // Create a new label
    Graphics g = lbl.CreateGraphics();    // Create the graphics for this label
    if (thisFont == null)
    {
        thisFont = lbl.Font;
    }
    return (int)g.MeasureString(text, thisFont).Width;
}

Using this method, I can calculate the width in pixels for any string I want using any font. Now that we know what the length of a text in pixels for the specified font will be, we can create the method to truncate the text:

public static string FitText(string text, int pixels, Font thisFont, string addAfter)
{
    Label    lbl = new Label();         // Create a new label 
    Graphics g = lbl.CreateGraphics();  // Create the graphics for this label
    SizeF    w;                         // Size object to be used for calculating
    float    available = pixels - 1;    // Adjust the available pixels to handle whitespace
    bool     isTruncated = false;       // Assume the string will fit
    string   result  = string.Empty;    // Will contain the result for this method
 
    // When there is no font specified, assign the label font as the font to be used
    if (thisFont == null) thisFont = lbl.Font;
    // When an AddAfter text was specified, calculate the length of
    // that text and adjust the available white space
    if (addAfter.Trim().Length > 0) available -= g.MeasureString(addAfter.Trim(), thisFont).Width;
    // If there is room to fit the string
    if (available > 0)
    {
        // Now assign the text to the result
        result = text;
        do
        {
            // Calculate the width of the Result string using the specified font
            w = g.MeasureString(result, thisFont);
            // If there aren't enough pixels available, truncate the string
            if (w.Width > available)
            {
                result = result.Substring(0, (int)((result.Length * available) / w.Width));
                isTruncated = true;
            }
        } while (w.Width > available);
        // If the string was truncated, we need to add the AddAfter string if
        // there was one specified
        if (isTruncated && (addAfter.Trim().Length > 0))
        {
            result += addAfter.Trim();
        }
    }
    return result;
}

The method above takes the text as the first argument. The second argument is the width from the label we need to fit the text into. The third argument would supply the font used to display the text. The last argument allows you to specify text that would follow the original text if the method would truncate the original text, for example "...". So now that this method is done, I can add the text to my label in the following way:

label2.Text = FitText("This is a very long text which will not fit the label in this situation",
label2.Width, label2.Font, "...");

The label would then display something like the following, which I think is a lot better.

Extending the TraceExtension attribute

As I wrote in an earlier post, I wanted to implement a simple tracing option on my new webservice. I needed to log the incoming and outgoing SOAP messages to a file. I found this link at Microsoft and got it to work. But I didn't think it had the flexibility I needed to make it useful for other webservices:

  1. I noticed, that the webservice would not work properly if the WriteOutput or WriteInput method failed. In my case, it failed because the webservice did not have proper access rights to the location where the log file was to be written. I refactored both methods to include try/catch/finally. The finally now makes sure that the webmethods that are tagged with the TraceExtension attribute continue to work if the TraceExtension fails. I'd rather have my webservice function as normal then always have log's written.
  2. Another thing was the lack of configurability. There was no way you could change the location of the logfile without re-compiling the webservice. And it was also not possible to change if only incoming or outgoing messages should be logged

So I made some changes to the code and added some small extra's.  You can click here to download the code with a sample webservice and test application.

Configurable 

As the webservice would always have a web.config, I added settings to the appSettings section. The settings can be used to configure the name and location of the webservice name, and the messages that will be logged:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<appSettings>

<add key="LogFile" value="C:\Logs\MyWebService.log"/>

<!--

Logtype can one of the following:

0 - No logging

1 - Log both incoming and outgoing messages

2 - Only log incoming messages

3 - Only log outgoing messages

-->

<add key="LogType" value="1"/>

</appSettings>

</configuration>

Safer

The WriteOutput and WriteInput methods in the standard code fail when the message cannot be written to the log file. That in turn causes your web methods in your web service to fail. I didn't want that to happen. If the logging fails, at least try to make sure that the web methods work as expected. I there for added try/catch/finally handling to these methods. Below is the updated version for WriteInput:

public void WriteInput(SoapMessage message)
{
    try
    {
        Copy(_oldStream, _newStream);
 
        // Check if we need to log incoming message
        if (_logType == LogType.LogInLogOut || _logType == LogType.LogIn)
        {
            FileStream fs = new FileStream(_filename, FileMode.Append, FileAccess.Write);
            StreamWriter w = new StreamWriter(fs);
            string soapString = (message is SoapServerMessage)
                ? "SoapRequest" : "SoapResponse";
 
            w.WriteLine("-----" + soapString + " at " + DateTime.Now);
            w.Flush();
            newStream.Position = 0;
            Copy(_newStream, fs);
            w.Close();
        }
    }
    catch
    {
        // Ignore any errors, we want the webmethods to work if this fails
    }
    finally
    {
        _newStream.Position = 0;
    }
}

 

Trouble shooting webservice extension

Yesterday, I was trying to implement a TraceExtension attribute for my webservices. I found this link at Microsoft which performs exactly that implementation. But, when I implemented this class in my webservice, I couldn't get it to work. I constantly got the following error message: Client found response content type of '', but expected 'text/xml'. After an hour or so, I was ready to pull out what hair remains on my head. And trust me, that isn't all that much to begin with.

Fortunately, helpfull colleagues came with the following tips:

  • The original code provided by the link above tries to write to a file on the local system. Make sure the IUSR has enough access rights to write to that location
  • The original code also builds a filename for the webservice using WebServiceType.FullName. That property can be empty. So there's no real file name. Change that to a real name.
  • If you want to debug what happens, attach the debugger to the aspnet_wp.exe process.

And using that, I finally got it to work. So thanks to Carlo Poli, Edward bakker and Jasper Defesche!

 

This is like the coolest keyboard ever!!!!

I just bumped into this one. A new keyboard, designed by a group of Russion industrial designers.

You probably think this is not really special. Well, just look at the really big, square, enter key below. Notice the small dot's? Yep, the key's are very small LCD displays.

Now that's cool, right? Gives you all sort's of possibilities, like switching from an english lay-out to a russian lay-out. When you play Quake, you finally see which key's do what function. And what about those programmable function keys that allow you to switch between applications.

Free Visual Studio 2005 and SQL Server 2005 learning stuff

The Microsoft E-Learning website is a great source for labs, clinics and other training material. It contains links to other sections of the website.

With the introduction of Visual Studio 2005 and SQL Server 2005 later this year, hopefully in November, the free E-Learning resources for these products are a great way to get you started. Assuming you haven't done so already. And even if you have used the beta's of these products already, there's always something that could be of interest to you:

A great way to see what your knowledge level is for these new products are the skill assesments. You can currently take assesments for:

The website also provides information about the various Microsoft Certification programmes, including the all new Microsoft Certified Architect program.

FTP connection in .Net applications

I've done it myself in VB6, tapping into the WinInet API in order to handle FTP stuff. But I needed something for C#. So I found code written by Peter Beedell on Code Project which solved my problem.

But tonight I found something that, at a first glance, looks even better: edtFTPnet. edtFTPnet is Open Source, licensed under the LGPL, the GNU Lesser General Public License. There's even an edtFTPnet/Pro, which provides SOCKS proxy support and secure FTP over FTPS. These are some of the features, supported by the Open Source version:

  • Full source code is provided.
  • Passive and active modes are supported (PASV and PORT).
  • Resuming of interrupted binary transfers supported.
  • Events for monitoring progress of data transfers.
  • Under the LGPL, so it can be embedded in commercial applications
  • API analogous to command line FTP program.

For my current project, I will continue to use the WinInet implementation provided by Peter Beedell. But next time I will definitely check out edtFTPnet.

Posted: Tue, Jul 12 2005 8:32 PM by Jan Schreuder | with no comments
Filed under:
Free online training for part of your MCAD

One of the exams required to get an MCAD certificate is “Developing and Implementing Web Applications with Microsoft C#™.Net and Microsoft Visual Studio® .NET “ (Exam 70-315, or Exam 70-305 when you prefer Visual Basic .Net). To prepare for this exam, you might want to follow Course 2310: Developing Microsoft ASP.NET Web Applications Using Visual Studio .NET. Well, then you're in luck.

For a limited time only, an E-Learning version for this course is available for free, on the MSDN website. That course would normally cost you $349 and should take about 17 hours to complete. It is a self-paced training course. After completing the course, you will be able to:

  • Explain the Microsoft .NET Framework and ASP.NET
  • Create a component in Visual Basic .NET or C#.
  • Create an ASP.NET Web application project by using Visual Studio .NET.
  • Add server controls to an ASP.NET Web Form.
  • Create and populate ASP.NET Web Forms.
  • Add functionality to server controls that are on an ASP.NET Web Form.
  • Use the Trace and Debug objects that are provided with Visual Studio .NET.
  • Use validation controls to validate user input.
  • Create a user control.
  • Access data by using the built-in data access tools that are available in Visual Studio .NET.
  • Use Microsoft ADO.NET to access data in an ASP.NET Web application.
  • Accomplish complex data access tasks from an ASP.NET Web application.
  • Access Extensible Markup Language (XML) data and read it into a DataSet.
  • Call an XML Web service from an ASP.NET Web application and incorporate the returned data into a Web application.
  • Store application and session data by using a variety of methods.
  • Configure and deploy an ASP.NET Web application.
  • Help protect an ASP.NET Web application by using a variety of technologies.
Posted: Mon, Jul 11 2005 10:31 PM by admin | with no comments
Filed under:
.Net 2.0 out performs J2EE

Microsoft previously published the results for case studies in which the performance of some elements of J2EE and .Net have been compared. The case studies have been created by Sun Microsystems to prove that J2EE outperformes .Net 1.1. The results now include comparisons between .Net 1.1 and 2.0. And the results of that comparison are very interesting as well. .Net 2.0 seems to significantly out perform .Net 1.1 and of course J2EE. An example can be seen in the image below which shows the TPS for an XML DOM build test, which is part of the Comparing XML Performance study.


Click the image to see a bigger version.

Another study on that same page compares developer productivity, application performance, manageability and reliability of .NET 1.1 on Windows Server 2003 to IBM WebSphere 5.1.02 on RedHat Linux. Below is the graph that compares developer productivity.


Click the image to see a bigger version.

Needless to say that Microsoft supporters already knew the outcome of this comparison.

Posted: Wed, Jul 6 2005 8:33 AM by Jan Schreuder | with no comments
Filed under:
Enterprise library June 2005 is out!

I was checking out the Patterns and Practices website at MSDN and noticed that Microsoft has released a new version of the Enterprise Library. The June 2005 version contains the same block as the version that was release in January 2005, as well as all the patches and improvements that have been release since the release in January.

The library can be downloaded from this location.The release notes can be found here.

Posted: Sun, Jul 3 2005 12:35 PM by Jan Schreuder | with 2 comment(s)
Filed under:
Giving something back to the community

A week ago I blogged about calculating the date for Easter. I found the original C++ code to do this on the Code Project web site, a web site I regularly check if I need code samples. Today I gave them something back in return.

I posted an article on Code Project on how to calculate a number of Christian Holidays. The class calculates the following holidays:

  • Easter Sunday
  • Good Friday (Friday before Easter Sunday)
  • Palm Sunday (1 week before Easter Sunday)
  • Whit Sunday (7 weeks after Easter Sunday)
  • Ascension Day (10 days before Whit Sunday)
  • Ash Wednesday (47 days before Easter)
  • First Sunday of Advent (The sunday between November 26 and December 3)

My way of saying thanks to the community.