GitHub Source Symbol IndexerJan9

Monday, 9 January 2012 by haemoglobin

Do you host your .NET library on GitHub?

Do you want to give developers who use your library the ability to step into your code while debugging, without them even needing to have git installed or your repository cloned on their machines?

Then the GitHub Source Indexer could be for you.

The GitHub Source Indexer is a powershell script that will recursively iterate over PDB files in the directory you specify, indexing the source symbol server links back to raw GitHub HTTP urls, which Visual Studio will load while debugging.

This powershell script was adapted from SourcePack (by Sebastian Solnica) which can be used if you have the full source on your machine and packed into a zip file. In his article, he also describes a lot of the science behind the source indexing of PDB files which is useful reading. Much of the source of the script is reused from SourcePack (also hosted on codeplex here) so credits and thanks to Sebastian.

There is another tool SourceServer-GitExtensions but will require Git and the repository to be installed locally (we also had trouble getting this tool working).

The first requirement before running the script is to have the Debugging Tools for Windows installed which is part of the Windows SDK which can be downloaded from here: http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=8279

As part of the installation, ensure the Debugging Tools for Windows option is selected as part of the install (install or deselect other options as you desire):

Untitled

Once complete, add C:\Program Files\Debugging Tools for Windows (x64)\srcsrv (or wherever it installed itself on your machine) into your PATH environment variable.

The essential steps of using the script are as follows – all from the command prompt:

  1. Find out what paths are currently indexed in the pdb file:
    srctool –r YourLibrary.pdb
    The output should have a original file path for every source file used in the compilation, lets assume the following for the example:
    C:\git\TestRepository\YourLibrary\LibraryClass.cs
  2. We want this to link to a GitHub URL such as:
    http://github.com/[username]/[RepositoryName]/raw/[branchtagname]/YourLibrary/LibraryClass.cs
    Confirm this URL matches the same version of the source that was used when the PDB file was created. An real example URL can be seen here: https://github.com/Haemoglobin/TestRepository/raw/release1.0/ExampleLibrary/LibraryClass.cs
    This is what the Visual Studio debugger will download into the IDE and step into.
  3. Take note of the beginning of the path in the first step, which will tell the script what to strip out to replace with the GitHub URL, i.e C:\git\TestRepository
  4. Run the powershell script as follows:
    powershell .\github-sourceindexer.ps1 -symbolsFolder "C:\git\TestRepository\YourLibrary" -userId "Username" -repository "RepositoryName" -branch "branchtagname" -sourcesRoot "C:\git\TestRepository" –verbose
    Where:
    • -symbolsFolder: Directory to recurse to source index all PDB files.
    • -userId: Your GitHub username.
    • -repository: Your project’s GitHub repository name.
    • -branch: The name of the branch or tag that matches the correct versions of the source files as when the PDB file was created. 
    • -sourcesRoot: The path that we will be stripping out from the beginning of the original file paths found in step 3 above to replace with the GitHub URL. 
    • -verbose: A optional powershell flag to have the script output more output information to the console
    • Note: Watch out for escaping backslashes! For example use "C:\git\TestRepository" not "C:\git\TestRepository\" as the latter will escape the ending quote of the powershell parameter.
  5. Run the following against the PDB file to confirm the GitHub source indexing information was written:
    pdbstr –r –p:ExampleLibrary.pdb –s:srcsrv
    Which will look something like the following:
    SRCSRV: ini ------------------------------------------------
    VERSION=1
    INDEXVERSION=2
    VERCTL=Archive
    DATETIME=01/09/2012 11:58:22
    SRCSRV: variables ------------------------------------------
    SRCSRVVERCTRL=http
    HTTP_ALIAS=
    http://github.com
    HTTP_EXTRACT_TARGET=%HTTP_ALIAS%/%var2%/%var3%/raw/%var4%/%var5%
    SRCSRVTRG=%http_extract_target%
    SRCSRVCMD=
    SRCSRV: source files ---------------------------------------
    C:\git\TestRepository\YourLibrary\LibraryClass.cs*Haemoglobin*TestRepository*
    master*YourLibrary/LibraryClass.cs
    SRCSRV: end ------------------------------------------------

You can now distribute this PDB file along with your library’s DLL, and the developer will be able to step into your source library code to assist their debugging session. Alternatively to distributing the PDB file with your library, you could also make it available through a symbol server (which I may save for another blog post).

There are a couple of things that the developer will need to setup in Visual Studio however before they can step into the GitHub source your PDB files reference:

  1. Make sure the symbol cache directory is set to a writable location (if not running Visual Studio as administrator ensure that the non-elevated user also has permissions to write here):
    image
  2. Ensure source server support is enabled and Enable Just My Code is unticked:

DebuggingGeneral
That’s it!

To test this locally, copy and reference your library’s dll/pdb pair from another project, but make sure you rename your original library folder you compiled from. This is because the original file path is not actually removed in the source indexing process, so if it is still there Visual Studio will load the original path as opposed to downloading from GitHub.

Reference the library, write some code against it and add a breakpoint before the library call. Use F11 to step into the library code, and if the file correctly downloads from GitHub it should load from your symbol server cache directory, similar to below:

image

Good luck!

[Update: If you use Resharper, you will also be able to step into the library code on GitHub at development time as you are navigating around the code, so you don’t even need to be in a debugger session for this to happen. Nice!]

Categories:   Development
Actions:   E-mail | Permalink | Comments

Patterns for Accessing App.config SettingsJan6

Friday, 6 January 2012 by haemoglobin

Here are some patterns I have used for accessing App.config settings which I’ve found to be quite clean. If you introduce an interface over top of the class you will also be able to stub it out for unit testing.

Consider the following application settings:

<appSettings>
  <add key="DelaySeconds" value="15"/>
  <add key="EndDate" value="2013-02-01 6:30pm"/>
</appSettings>

In code, timers usually require millisecond values over seconds so we do a conversion here using the Lazy object showing how any calculations can be done once and when required. We can then access these with the class below:

public class AppSettings
{
    private readonly Lazy<int> _delayMilliseconds;
    
    public AppSettings()
    {
        _delayMilliseconds = new Lazy<int>(() => GetMilliseconds("DelaySeconds"), true);
    }

    public int DelayMilliseconds
    {
        get { return _delayMilliseconds.Value; }
    }

    private int GetMilliseconds(string configSettingName)
    {
        var seconds = GetSetting<double>(configSettingName);
        return Convert.ToInt32(seconds * 1000);
    }

    public T GetSetting<T>(string key)
    {
        string value = ConfigurationManager.AppSettings[key];
        if (value != null)
        {
            try
            {
                var converter = TypeDescriptor.GetConverter(typeof(T));
                return (T)converter.ConvertFrom(value);
            }
            catch(Exception ex)
            {
                var logError = string.Format("Unable to convert configuration value for {0} to type {1}", key, typeof(T).Name); 
                Console.WriteLine(logError);
                Console.WriteLine(ex.ToString());
            }
        }

        return default(T);
    }
}

You can either wrap each setting in its own property or access it directly based on the string key as below:

var appSettings = new AppSettings(); 
Console.WriteLine(appSettings.DelayMilliseconds); 
Console.WriteLine(appSettings.GetSetting<DateTime>("EndDate"));

The output being as below:

15000
01/02/2013 18:30:00
Categories:   Development
Actions:   E-mail | Permalink | Comments

Access to modified closureSep6

Monday, 6 September 2010 by haemoglobin

Let’s play! Lately, I have been doing a fair bit of Silverlight development which forces an asynchronous style of development. After installing Resharper I would often see the message “Access to modified closure”. This happens when you have code that looks like this (note following is a contrived example but similar to the type of code you might end up writing when writing against asynchronous WCF services): 

   
class Program
    {
        class Person
        {
            public string Name;
            public string Greeting
            {
                set
                {
                    Console.WriteLine(String.Format("Setting {0} to {1}", Name, value));
                }
            }
        }
       
        static void Main(string[] args)
        {
            var peopleList = new List<Person>();
            peopleList.Add(new Person() { Name = "John Smith" });
            peopleList.Add(new Person() { Name = "Bobby Jones" });

            foreach (var person in peopleList)
            {
                GetGreeting(person, s => person.Greeting = s);
            }

            Console.ReadLine();
        }

        static void GetGreeting(Person person, Action<string> messageResponse)
        {
            messageResponse(String.Format("Hi, {0}!", person.Name.Split()[0]));
        }
    }

Resharper will actually underline the lambda expression above (s => person.Greeting = s) with the aforementioned message – sometimes this can be safe to ignore depending on what you are doing. In the above example what do you think the output should be?

No surprises actually:

image

But, some problems occur if the call to GetGreeting is asynchronous, as Silverlight callbacks to the server always are.

We simulate this by making GetGreeting asynchronous instead:

static void GetGreeting(Person person, Action<string> messageResponse)
{
    var worker = new BackgroundWorker();

    worker.DoWork += (s, e) =>
                         {
                             var parameters = (Tuple<Person, Action<string>>)e.Argument;
                             Person p = parameters.Item1;
                             Action<string> callback = parameters.Item2;

                             callback(String.Format("Hi, {0}!", p.Name.Split()[0]));
                         };

    worker.RunWorkerAsync(new Tuple<Person, Action<string>>(person, messageResponse));
}
 

Guess what we have now? Interesting to know that it will always be the following:

image

Notice that it is setting the two greetings on the same Bobby Jones object. Now that’s what Resharper is warning you about when it is saying “Access to modified closure” – to understand what is going on here I recommend reading the following post:
The implementation of anonymous methods in C# and its consequences

Essentially once you know how things work under the hood it makes perfect sense – the Person object is set as an instance field on a generated class that contains the anonymous method, and its reference is updated by the foreach loop rapidly to the last person object in the list, and then by the time the asynchronous method(s) have a chance to act on it, it ends up acting on the last object in the List twice.

In the application I am working on I need to pre-load a lot of data up front and have the UI display an in progress style loading panel. To solve the problem above, as well as not to flood the server with a tonne of requests all at once, I decided to load each object one at a time and display feed back. I could have used a Queue or an Enumerator for this, however I needed to display “Loading 3 of 34” type information, keeping the current index information outside of the Queue or Enumerator was messy and repeated, so ended up implementing a Iterator class that I can use for this (a quick search didn’t reveal anything like this but it was fast enough to make – not thread safe but suitable for my use): 

public class Iterator<T> where T : class
{
    private int _current = -1;
    public int CurrentIndex
    {
        get
        {
            return _current;
        }
    }

    public int Count
    {
        get
        {
            return _items.Count;
        }
    }

    readonly List<T> _items;
    public Iterator(List<T> items)
    {
        _items = items;
    }

    public T Next()
    {
        _current++;
        if (_current >= _items.Count)
            return null;
        else
        {
            return _items[_current];
        }
    }

    public T Current()
    {
        return _items[_current];
    }
}


class Program
{
    class Person
    {
        public string Name;
        public string Greeting
        {
            set
            {
                Console.WriteLine(String.Format("Setting {0} to {1}", Name, value));
            }
        }
    }
   
    static void Main(string[] args)
    {
        var peopleList = new List<Person>();
        peopleList.Add(new Person() { Name = "John Smith" });
        peopleList.Add(new Person() { Name = "Bobby Jones" });

        var peopleIterator = new Iterator<Person>(peopleList);
        LoadNextPersonGreeting(peopleIterator);
        Console.ReadLine();
    }

    static void LoadNextPersonGreeting(Iterator<Person> peopleIterator)
    {
        Person nextPerson = peopleIterator.Next();
        if (nextPerson != null)
        {
            Console.WriteLine("Loading {0} of {1}", peopleIterator.CurrentIndex + 1, peopleIterator.Count);
            GetGreeting(nextPerson, s =>
            {
                nextPerson.Greeting = s;
                LoadNextPersonGreeting(peopleIterator);
            });
        }
    }

    static void GetGreeting(Person person, Action<string> messageResponse)
    {
        //Same as before.
    }
}

image

I thought this was quite interesting and worthy of a blog post,

Thanks,
Hamish

Categories:   Development
Actions:   E-mail | Permalink | Comments

ASP.NET Reverse Proxy ConsiderationsJul4

Sunday, 4 July 2010 by haemoglobin

What is a Reverse Proxy

During lead developer roles of previous ASP.NET projects, I’ve needed to deploy into some fairly heavy enterprise infrastructure - once needing to deal with some unexpected behaviour caused by reverse proxy’s. I’ll describe in this article some things to keep in mind when doing this to ensure everything still runs smoothly and correctly all the way from the development environment to production.

A reverse proxy has a few functions, one function is acting as the network load balancer as I talked about in my previous post Web Farm Considerations. It can also be the point that processes SSL encryption.

Many people might already familiar a standard “proxy” that they may have needed to configure their browser to use to make connections to the internet (typically from inside a company network). More specifically this is known as a “forward proxy” and is to do with outgoing traffic, i.e. instead of the browser making a connection directly to a website, it will send the request first via a proxy server somewhere in the company’s network. The proxy server may be the only machine on the company network that can access the internet and gives the company further control over blocking of certain sites, monitor outgoing requests, virus scanning, caching etc.

A reverse proxy on the other hand sits on the server side – and is essentially the opposite of a forward proxy.

Application Path Issues

image

The scenario described here is when your ASP.NET application (ApplicationX) is to be deployed to a subdirectory of an already existent company wide domain (www.company.com), i.e to http://www.company.com/ApplicationX.

The user’s browser will connect to the reverse proxy which has a public address such as https://www.company.com/ApplicationX (so essentially connecting to it without realising it as opposed to the forward proxy that needs to be configured) – which will then forward the request to a server internal to that network such as http://internal05/ApplicationX to do the real processing of the request and dishing up the web content to the user. Acting as a NLB (Network Load Balancer) the request could also be redirected to http://internal0[1-4]/ApplicationX unbeknown to the user. These internal0[1-5] servers are only accessible within the company network, behind the firewall and not accessible directly from the cloud/internet.

Now – here is the issue to keep in mind when deploying in this type of scenario – it’s quite possible for servers internal01-05.company.com to be servers dedicated to ApplicationX – in this case it would seem natural to simply set the default website on these to serve ApplicationX i.e directly at http://internal05.company.com.

The problem with this is ASP.NET will send virtual addresses such as WebResources.axd (some more info about WebResource.axd in my post Securing Static (Non-ASP.Net) Files) back to the client browser as the absolute address “/WebResource.axd”. This will cause the client browser to make requests to https://www.company.com/WebResource.axd – not good ! Instead it should be https://www.company.com/ApplicationX/WebResource.axd .

To achieve this, the option is to create a virtual directory on the internal server called ApplicationX so that it is served from http://internal05.company.com/ApplicationX (matching the reverse proxy’s URL structure). ASP.NET will now return the absolute address “/ApplicationX/WebResource.axd” back to the client browser which will resolve correctly behind the reverse proxy.

In terms of linking to resources yourself, ensure that you don’t use something like Request.Url. This will work in your development environment, but when deployed behind the reverse proxy – Request.Url will actually return http://internal05.company.com/ApplicationX (as far as the ASP.NET application is concerned, it is serving content from this location as the reverse proxy has made a request to the internal server with this URL). Obviously from the client browser however any references to this address will not work since this server is behind the company firewall.

Instead, make use of the special character “~” wherever possible (in conjuction with ResolveUrl where necessary) which will resolve to “/ApplicationX”. Here are some examples (note that server side controls “~” can be specified and interpreted directly within the properties themselves without use of ResolveUrl):

<asp:Image runat="server" ID="image" ImageUrl="~/Penguins.jpg" /> 
<img alt="Penguins" src='<%=ResolveUrl("~/Penguins.jpg") %>' />

This will mean the client browser will request items back to http://www.company.com/ApplicationX as well as ensure everything still works in the development environment.

Using Request.ApplicationPath instead of “~” will probably cause issues if you are running your Visual Studio web server development environment from the root directory. Linking to resources from the root directory - Request.Application path returns “/” and you end up with with a request to //Penguins.jpg, which will fail, such as below: 

<img alt="Penguins" src='<%=Request.ApplicationPath + "/Penguins.jpg" %>' />

The solution is to either use “~” or alternatively run your development environment from a virtual path instead of the root directory if you do prefer using Request.ApplicationPath.

In summary, before deploying to a more complicated infrastructure than a simple single server scenario, it pays to think through any potentially surprising behaviour you might see. To save potential delays further down the track it can be wise to put the time aside to setup a test environment first that includes the reverse proxy, load balancing servers etc to ensure everything still works as expected.

Good luck! Hamish

Categories:   Development
Actions:   E-mail | Permalink | Comments

ClickOnce Not Installing Latest VersionsJun29

Tuesday, 29 June 2010 by haemoglobin

I have recently had an interesting experience debugging some ClickOnce issues with my WPF Inspirational Quote Management System.  Essentially, I would deploy a new version of the application - but some users after choosing File -> Check For Updates, would receive a message saying that the latest version is already installed - which I know was not the case.

I could not figure out why it would not be picking up the new version of the application. One user being a friend, I was able to work with them using TeamViewer to try a few things on their computer, including inspecting the contents of the ClickOnce installer file (http://www.hamishgraham.net/files/WPFQuoteManagement/WPFQuoteManagement.application) that they receive on their computer after browsing to the URL. I noticed that the contents of the file downloaded was quite old compared to what I would get if I downloaded from the same URL on my computer. Straight away this was smelling of caching problems. 

No amounts of Control-F5 would fix this – only appending a question mark on the end of the URL would retrieve the latest version (common trick to bypass web caches), but this still does not help the WPF application which browses to the aforementioned URL (under the hood using ClickOnce) without any question mark for the update. 

I needed to confirm that this was indeed a web cache issue, so I did this by firing up Fiddler, and running the WPF application’s check for updates function again. Fiddler intercepts all HTTP traffic to/from the computer from all applications and not just a web browser - very handy in this case.

On my friends computer, the WPF application would receive the following HTTP headers for the ClickOnce .application file when checking for updates:

HTTP/1.1 200 OK
Content-Type: application/x-ms-application
Last-Modified: Tue, 01 Jun 2010 05:21:36 GMT
Accept-Ranges: bytes
ETag: "aeb494e4a1cb1:0"
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Fri, 25 Jun 2010 04:20:46 GMT
Via: 1.1 bc5
Content-Length: 5769
Connection: Keep-Alive
Age: 343128

On my computer on the other hand, it would look like:
HTTP/1.1 200 OK
Content-Type: application/x-ms-application
Last-Modified: Mon, 28 Jun 2010 05:41:10 GMT
Accept-Ranges: bytes
ETag: "eec57e838416cb1:0"
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Tue, 29 Jun 2010 04:08:22 GMT
Content-Length: 5765
Connection: Keep-Alive
Age: 0

I’ve highlighted the problem areas on my friend’s HTTP response. The file was being served from “1.1 bc5” which is the name of TelstraClear’s web cache (my friend being with TelstraClear), which by the looks of it holds a version that I last modified on the 1st June. The date field (25th June) indicates when the web cache last checked that the file was still valid.

Now, here is the problem, without explicitly setting a cache expiry for the file, the web cache is at its own liberty to decide when it deems appropriate to check whether the file is still valid. Without any explicit cache expiry existent in the HTTP header, web caches use heuristics are used to determine when to check validity again by doing calculations on Date and Last-Modified… i.e if the gap between the time I last checked validity of the cached file and when the file was last modified is large, it probably means the file isn’t changing very much, so wait even longer before checking for validity again.

I found someone who has already solved this issue http://www.codeproject.com/KB/dotnet/ClickOnceContentExpiratn.aspx which I implemented, however slightly differently by adding the following line instead into the web.config under the <handlers> node:

<add name="ClickOnce" verb="*" path="*.application" type="CustomHttpHandlers.ClickOnceApplicationHandler" resourceType="Unspecified" preCondition="integratedMode"/>

I then needed to enable the IIS7 Integrated Pipeline on the webserver which ensures all file types are routed through ASP.NET runtime for the HTTP Handler to be executed for the .application file, and the cache expiration explicitly set.

Retrieving the ClickOnce .application file now comes back with the following HTTP headers:

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/x-ms-application
Expires: -1
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Tue, 29 Jun 2010 09:49:23 GMT
Content-Length: 5765
Connection: Keep-Alive

This should hopefully tell any web caches ISP’s are using that this file mustn’t be cached – meaning latest versions of the application can be deployed promptly to all users. It will take a few days until the web caches finally refresh before I can test this works as expected, but hopefully this will be a win.


Extra Resources

Categories:   Development
Actions:   E-mail | Permalink | Comments

Delete the Currently Playing FileApr26

Monday, 26 April 2010 by haemoglobin

For years now I’ve had songs in my music collection that are so terrible I shudder when they come on – but the process of actually deleting the file so I’d never hear it again has always been so painful I never do it. So end up listening to the thing again and again.

Applications like iTunes, VLC and Windows Media Player all work the same way by deleting the song from the play list and not the file system itself. To delete from the file system you usually have to go through some complicated process to find the file path, open windows explorer and then delete it from there.

I’ve googled a bit over time for plugins and so on that let you actually delete the currently playing song but I’ve never really had much luck so thought I would bite the bullet and make something up.

I had grand plans of having a lovely little WPF application that sits in the system tray with an assigned keyboard hotkey to delete the currently playing song. I thought I would do this by just scanning the file handles the media playing application has hold of, find the mp3 / wma file and then delete it. Since .NET isn’t very capable at getting low level file handle information without going into a whole lot of unmanaged code I thought I would just use the output from the sysinternals Handle application. This needs administrative privileges however to run, and I subsequently found out that it is impossible to run an external process from .NET with elevated privileges (contrary to many posts around the internet) – on Windows 7 with UAC enabled anyway. This guy also found this out the hard way.

So I’m sorry, I didn’t end up making a pretty application but I did end up getting something going that works (a console application) – but is a bit geeky for the average user unfortunately.

However I thought I would share it anyway. Here are some steps to set it up:

  1. First of all, download DeleteCurrentlyPlaying.zip and extract to a directory. If you get an error when running it later, you may not have the .NET Framework 3.5 installed. 
  2. Open a command prompt with Administrative rights. This guide tells you how to do this. On Windows XP you won’t need to worry about this.
  3. Navigate to the folder with the files in it e.g “cd c:\path\to\downloads\DeleteCurrentlyPlaying”
  4. Now run the following if your song is currently playing in Windows Media Player, VLC Player or iTunes respectively (this is just the process name changing):
    handle –p wmplayer | DeleteCurrentlyPlaying
    handle –p vlc | DeleteCurrentlyPlaying
    handle –p itunes | DeleteCurrentlyPlaying
  5. For your piece of mind, the file isn’t actually deleted, it is moved to a subfolder “To Delete” for you to delete at some point. Also if you would rather download the source and compile it yourself, you can find it here.

The application will wait until the file has been released by the application before it is moved (in the case of Windows Media Player it seems it can be moved while it is being played).

It should look something like this:

image

You can just leave this console window open, and then hit the up arrow to repeat the last command and hit enter again when the next one to go comes on.

UPDATE 24/9/2011

I have found a way to make execution of this slightly easier. Create a .bat file in the unzipped directory with the following contents:
cd path_to_unzipped_dir
handle –p wmplayer | DeleteCurrentlyPlaying     (or replace wmplayer with whatever your music player process is)

Now, create a shortcut to this bat file and right click –> properties –> Shortcut –> Advanced –> Check “Run as administrator”.
The reason we need to cd to the unzipped dir in the batch file above is because when we run cmd as administrator it seems to ignore the “start in” directory and takes you to c:\windows\system32.

If you are using a productivity tool such as Launchy you can then create an entry direct to the shortcut using the Runner addin.

Categories:   Development
Actions:   E-mail | Permalink | Comments

Understanding Action<T> and Func<T, TResult>Apr22

Thursday, 22 April 2010 by haemoglobin

In .NET 3.5 there are two new delegate types Action<T> and Func<T, TResult>. 

There are other overloads for Action<T> and Func<T, TResult> if you need to provide more than one parameter, e.g:
- Action<T1, T2, T3>
- Func<T1, T2, T3, TResult>

I wanted to test my understanding of these by making a quick console app that uses them. The example below is extremely contrived and something you would not do in practice of course but I believe it to break down the core essence of their use, so you can use your imagination from there as to how you would use them.

It actually started off much more simple but then I intentionally beefed it up including plenty of generics, and multi-lined / multi-parameter lamba’s so if you understand this snippet you know you also have a good grasp of those too.

        static void Main(string[] args)
        {
            int result = DoStuffToSomething<DateTime, DateTime, int>(
                DateTime.Now, 
                DateTime.MaxValue,
                date => {
                        Console.WriteLine(date.ToShortDateString()); 
                        Console.WriteLine(date.ToLongTimeString());
                    }, 
                (date1, date2) => (date2 - date1).Days);

            Console.WriteLine(result.ToString() + " days before .NET DateTime explodes."); 

            Console.Read();
        }

        static R DoStuffToSomething<T1, T2, R>(T1 something, T2 somethingElse, Action<T1> myAction, Func<T1, T2, R> myFunction)
        {
            myAction(something);
            return myFunction(something, somethingElse);
        }

Prints:
  22/04/2010
  12:48:12 p.m.
  2918175 days before .NET DateTime explodes.

Good to know I guess.

Also note Action<T>’s use in the framework such as the ForEach method on a generic List. This can be used like so (as taken from http://msdn.microsoft.com/en-us/library/bwabdf9z.aspx):

    static void Main()
    {
        List<String> names = new List<String>();
        names.Add("Bruce");
        names.Add("Alfred");
        names.Add("Tim");
        names.Add("Richard");

        // Display the contents of the list using the Print method.
        names.ForEach(Print);

        // The following demonstrates the anonymous method feature of C#
        // to display the contents of the list to the console.
        names.ForEach(delegate(String name)
        {
            Console.WriteLine(name);
        });
    }

    private static void Print(string s)
    {
        Console.WriteLine(s);
    }

I would also add to the MSDN example to show how the same can be done using a lambda expression:

    names.ForEach(name => Console.WriteLine(name));

When these new language features come out, I think it is good practice to at least get an understanding of them, so when the right situation presents itself you have a new and possibly more efficient/readable option to use.

Categories:   Development
Actions:   E-mail | Permalink | Comments

WMD Markdown Editor SyntaxHighlighter IntegrationApr21

Wednesday, 21 April 2010 by haemoglobin

For my blog, I use SyntaxHighlighter to format code snippets (which I believe to be the best code formatting solution out there for a few reasons). The problem is however that it requires you to wrap your code in <pre class="brush: c#"> your code goes here </pre> tags – which can be a pain.

The WMD Editor control (or the stackoverflow open source port) on the other hand has a convenient button for "code" (or using the Ctl-K hotkey) that will indent the snippet in such a way that when rendered by Markdown (whether in the WMD Editor’s preview pane with the server side MarkdownSharp for example) it will be wrapped in <pre><code>your code snippet</code></pre> tags.

This format won't be highlighted by SyntaxHighlighter by default however.

Without wanting to modify SyntaxHighlighter my solution to this was to use jQuery to transform all instances of:

<pre><code>code snippet</code></pre>

rendered on the page to:

<pre class="brush: c#">code snippet</pre>

After this has been done, SyntaxHighlighter will be able to format the code snippet as it usually would.

I’ve created the following jQuery snippet to do this (which also goes to demonstrate the power of jQuery):

	//Find all <pre> tags that have a <code> tag child, and add the "brush: c#" class to the <pre> tag.	
	$('pre:has(code)').addClass('brush: c#'); 
	//Find each <code> tag (with a <pre> parent), and replace it’s contents with itself leaving only the <pre> tag behind. 
	$('pre>code').each(function(index) { 
		var cnt = $(this).contents(); 	
		$(this).replaceWith(cnt);    
	});  

The end result being you will have beautiful syntax highlighting or your code snippets with a simple click of the WMD Editor's 'code' button (or the Ctl-K hotkey).
If you wish to use another brush, you can still explicitly define a <pre> tag as normal specifying a different SyntaxHighlighter brush.

ASP.NET Wiki Control with Markdown

I am hosting an open source project that wraps the WMD Editor and MarkdownSharp projects together into a convenient wiki control over Linq to SQL that you can embed in any ASP.NET website (also with special instructions for installing into BlogEngine.NET for a better page editing solution).

I have just updated the latest version to include SyntaxHighlighter integration and will use javascript to detect for the presence of jQuery and SyntaxHighlighter and, if found, will run the jQuery code mentioned above to format your code snippets automatically through SyntaxHighlighter.

More information on the control can be found on the ASP.NET Wiki Control with Markdown download page.

Categories:   Development
Actions:   E-mail | Permalink | Comments

Web Farm ConsiderationsApr8

Thursday, 8 April 2010 by haemoglobin

Background

I have been involved with ASP.NET deployments for some high load scenarios where the same exact copy of a web application is deployed to multiple servers and placed behind a network load balancer (NLB) – also known as a web farm.

Requests to the website first arrive at the NLB, and are then directed off to a web server that is available to handle the request (the web server allocated depends on a number of load balancing algorithms the NLB server can use).

When deploying an ASP.NET application to a web farm for load balancing there are a few things to consider.

Session State

Session information in ASP.NET simply speaking is the ability to associate some information against a particular user as they are clicking through your site by using the .NET Session object. Behind the scenes the user session is tracked through a single non-persistent cookie (removed when the browser is closed) named ASP.NET_SessionId. The cookie contains a single ID that associates that user back to their session information on the server.

The actual information can be stored on the server in one of three ways – but only two of which will work when deploying to a web farm:

InProcThis is the default. InProc stores the session information in memory of the ASP.NET worker process on the server. This cannot be used with load balanced servers since if the user is sent to another server on a subsequent request, that server will not have that user’s session information available in its local worker process memory space.

StateServerWith this option, all web servers in the web farm store session information in the memory of a single process (a Windows service called “ASP.NET State Server”) preferably on a separate machine. This option works for web farms, but is 15% slower than InProc. This however of course is offset by having the extra servers processing requests.

SQLServer Using SQL Server, session information is serialized and stored to a SQL Server database. This is 25% slower than InProc, however SQL Server can be setup as a failover cluster which has reliability advantages over StateServer which is a single point of failure. This option can also survive a SQL Server restart; if StateServer on the other hand is restarted all session information will be lost.

Whether you choose StateServer or SQLServer is a trade-off between reliability and speed.

Machine Key

ASP.NET hashes ViewState by default to ensure that it hasn’t been tampered with before being sent back to the server. Out of the box the key used to generate the hash is a random one generated when the application pool starts. There is also a decryption key that is used to encrypt forms authentication tokens (also auto generated).

This has two problems:

  1. If the Application Pool restarts (by sysadmin or automatically through inactivity or scheduled recycling) a new validation/decryption key will be generated, and a user on a subsequent post back will receive a ViewState validation error or be logged out.
  2. If the user is sent to another server in the web farm on post back, the other server will have it’s own validation/decryption key, and the user will receive a ViewState validation error or be logged out.

So in order to work with a web farm it is necessary that all servers in the farm use the same validationKey and decryptionKey values and not have them auto generated.

A good codeproject article describes how to do this here http://www.codeproject.com/KB/aspnet/machineKey.aspx

<machineKey 
validationKey="E36B… CE0260028"
decryptionKey="DEF1F… 7F7C0BCCF85"
validation="SHA1" decryption="AES"/>

Also note that it is possible to encrypt ViewState (instead of just making it tamper proof) by setting the validation property to 3DES. This however incurs a performance hit so it is better to store sensitive information in the Session to avoid having to do this.

Storing / Sharing Files

Another problem exists when dealing with file uploads / downloads (when using the file system and not storing files in the database). All servers in the web farm need to be pointing to a common directory for the file store, otherwise if they are pointing to local directories the files will be split across them and sometimes exist and sometimes not depending on what server the user was sent to.

This can be overcome by setting up IIS Virtual Directories on the websites in the web farm that point to a common network share (on a file server somewhere on the network).

In order to test this concept locally for this blog post, I first created a directory c:\Test and turned on network sharing on this directory so that I can now browse to it through the UNC path \\HAEMOGLOBIN-PC\Test (in practice this would point to a share on another machine).

Within IIS7, the virtual directory “Uploads” can then be added that points to this share and will look something like this:

image

This allows the network share location to be maintained and controlled by system administrators – the only other thing to be aware of is setting up the correct permissions for the file share to be accessed and written to. This will depend on whether identity impersonation is enabled or what account the anonymous user is running as.

Coding against this is simple, saving a file is simply a process of using MapPath and the virtual directory name (this allows the system administrator to change the UNC location at a later point through IIS):

FileUpload1.SaveAs(MapPath(@"/Uploads/" + FileUpload1.FileName)); 

The above will be saved by IIS to \\HAEMOGLOBIN-PC\Test (as configured before and this could be on another machine) which in turn resolves to c:\Test on that machine.

In terms of providing a link to download a file - it would simply look like:

<a href="/Uploads/uploadedFile.zip">Uploaded File</a>

This will (once again through the IIS virtual directory mapping) download the file from the common file share location on the network and work for any server the user happens to be on in the web farm.

Hope this helps :)

Categories:   Development
Actions:   E-mail | Permalink | Comments

Versioning a Multi-Component SystemJan21

Thursday, 21 January 2010 by Haemoglobin

1  A lot of the systems that I have worked on have involved more than one component. For example, instead of just an ASP.NET website, there would also be some sort of windows service, maybe a windows forms component, or independent modules and libraries working within those components – all working together to form a final solution.

This tends to create a bit of a versioning and deployment nightmare and you need to have a good solid strategy around it before launching into things. I have tried a couple of approaches.

For one project, I had an automated build script that would go through and modify the version number of all the assemblies, build all the components and label the version from the root in source control. All components would then be redeployed for every release, regardless of whether they have changed or not. This removed human error in deployments as everything was automated, and the deployment steps were always exactly the same for each release so even those could be automated.

This worked pretty well for this project, because there were so many developers that it would have been too time consuming to do a full version to version diff to figure out which components have changed for each release and to deploy only those. Yes there would be release notes on what has changed for each of the components as written by project management or the developer, but that would be reliant on how dutiful Mr developer happened to be at the time, and it’s possible little “tidy” ups were done, or refactorings in components that do not end up appearing on release notes. So one answer is just to test and redeploy everything (this is where automated testing can be very useful also to test for regressions across the system). The only problem with it is you potentially end up deploying a lot of unchanged stuff – albeit just with updated version numbers, all for potentially one small change in one of the components.

For another project – there were far fewer developers, and it was quite easy to just know what components were being changed for each release – so it was possible to just deploy those that were being updated. I came up with the concept of a system version.

Say if you have the following structure in your source control repository for your software solution:

  • MySolution
    • ASP.NET Website
    • Windows Forms Application
    • Windows Service
    • Reporting Services Reports
    • Database Scripts

When you deployed the first version to production, imagine everything was versioned at 1.0.0. All assemblies / exe’s would have been deployed as version 1.0.0 (or using other techniques for database scripts like updating the database version row to this), and the label Version_1_0_0 (or similar) then applied to the MySolution root in source control.

This is in contrast to labelling each subcomponent separately in source control and keeping a configuration management register updated with what versions are deployed where and what versions are all working and tested with what other component versions – uggh.

Now – say that a bug in the windows forms application is reported – it makes sense to just send out a new version of just that, not everything. You make the change, and update the windows forms application’s version to 1.0.1. Now, the solution is is labelled with Version_1_0_1 from the root where 1.0.1 is effectively the new system version. Note however that the rest of the sub-components are still set at version 1.0.0 (literally within the AssemblyInfo.cs classes) – but the 1.0.1 label spans across them, effectively grouping the various current sub-component versions under the 1.0.1 system version umbrella.

Now – lets say a whole lot of work is done across all the different components to create a new feature asked for that will become version 1.1.0. During this time, another small issue is found in production – this time in the windows service. Since we are in the middle of development of version 1.1.0, which is subsequently unstable – we must branch the solution from version 1.0.1 (using the source control branching functionality). Here we make our change to the windows service, update it’s assembly version to 1.0.2 and then label the root of the branch as system version 1.0.2. We then deploy just the windows service to the client.

If we were deploying this solution to multiple clients, who for some reason were running on different versions, you can easily recreate in the development environment the version that they have running in their environment as long as you know their system version. Note that this must be recorded somewhere – but in this case it’s just one number per system deployment, as opposed to a complex set of versions of all the components installed. Pulling that label out of source control will retrieve all the subcomponents in their correct version as deployed for that system version, and consequently retrieve exactly what is running in production for each component.

The only danger with this technique is the possibility of a component being changed (maybe a developer deciding to re-factor some previous work), and not having this component deployed along with the next system version. This would effectively create a mismatch between what is deployed and running on the client’s system and the code associated with that system version in source control. This creates unreproducible bugs and other issues. To solve this, a quick and easy technique should be devised to query source control to see what components have been “touched” since the last release.

I would be interested to hear how others go about versioning in these sorts of situations. I may make a follow up post at some point about database versioning, and UAT deployment techniques.

Categories:   Development
Actions:   E-mail | Permalink | Comments

Powered by BlogEngine.NET 1.6.1.0 | Design by styleshout | Enhanced by GravityCube.net | 1.4.5 Changes by zembian.com | Adapted by HamishGraham.NET
(c) 2010 Hamish Graham. Banner Image (c) Chris Gin