How to install BT Netprotect on Windows 7

After installing Windows 7 I realised I needed to install my antivirus software so off to BT to download Netprotect. However, the download page incorrectly assumes that if the OS isn’t XP or Vista then it must be a really old version of Windows – Bzzzt. I first tried to persuade IE to launch in compatibility mode but to no avail. So I donwloaded Firefox, went to the properties, switched compatbiblity mode to run as Vista and downloaded NetProtect – fooled it.
 
 

Sharing ASP Session state with Silverlight

I’ve been working on a Silverlight project that where the SL application is used within an authenticated ASP.net site. During my testing I found a problem where using Silverlight 3’s Out-Of-Browser feature seem to lose the session token between calls to the site, i.e. I could logon but the next call would fail as if the user had not logged on. After a couple of Twitter conversations it became apparent that it should work. So I decided to take my testing back to basics, so first off can a Silverlight application use ASP session state?

  1. Create a basic Silverlight application – create a Silverlight application with a web project to host it
  2. Create a basic web service – with the web project selected add a new Silverlight WCF service, called SessionTest.svc
    image
  3. Implement some very simple interactions with the Session State

    [ServiceContract(Namespace = "")]

        [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

        public class SessionTest

        {

            [OperationContract]

            public void SetState(string value)

            {

                // Add your operation implementation here

                HttpContext.Current.Session["TestState"] = value;

                return;

            }

     

            [OperationContract]

            public string GetState()

            {

                // Add your operation implementation here

                return (string)HttpContext.Current.Session["TestState"];

            }

        }

  4. Add a Service Reference from your Silverlight application to your service, add appropriate using statements to your code-behind.

  5. Create some simple controls in your Silverlight application

    <StackPanel>

        <StackPanel Orientation="Horizontal">

            <Button x:Name="ButtonGetState"  Content="Get State" Click="ButtonGetState_Click" Width="60" ></Button>

            <TextBlock x:Name="TextBlockCurrentState" Width="100"></TextBlock>               

        </StackPanel>

        <StackPanel Orientation="Horizontal">

            <TextBox x:Name="TextBoxNewState" Text="" Width="100"></TextBox>

            <Button x:Name="ButtonSetState" Content="Set State" Click="ButtonSetState_Click" Width="60"></Button>

        </StackPanel>

    </StackPanel>

  6. Add code to the Silverlight application to communicate with the Service

    private void ButtonGetState_Click(object sender, RoutedEventArgs e)

            {

                SessionTestClient client = new SessionTestClient();

                client.GetStateCompleted += (object completedSender, GetStateCompletedEventArgs completedE) =>

                    {

                        if (completedE.Error == null)

                        {

                            TextBlockCurrentState.Text = completedE.Result;

                        }

                    };

                client.GetStateAsync();

            }

     

            private void ButtonSetState_Click(object sender, RoutedEventArgs e)

            {

                SessionTestClient client = new SessionTestClient();

                client.SetStateCompleted += (object completedSender, AsyncCompletedEventArgs completedE) =>

                    {

                        if (completedE.Error == null)

                        {

                            TextBlockCurrentState.Text = "";

                        }

                    };

                client.SetStateAsync(TextBoxNewState.Text);

            }

  7. Run the code, you should see that after you set a value you can retrieve the same value.

So we now know for sure that we can communicate with ASP.net and share the session state with the page. If you make the Silverlight application OOB (select project properties and check the OOB box) you’ll see that it continues to work without any problems. So this is good news, all I have to do now is track down why it isn’t working in my real application.

Remote debugging – value as being optimized

Surley one of the most annoying problems with remote debugging is after finally getting a connection, the correct pdb’s, the correct source and a breakpoint hit you examing the values to be faced with a big red cross saying the value has probably being optimized and you cannot view it. I’m not absolutley sure of the reason but I guessed that CLR had optimised it because the code had run before the debugger was attached. So my tip is to try and attach the debugger before the code is run. Obviously not the easiest thing to do every time but if you can do this then the CLR will not optimize the values aways. Hopefully someone out there will provide a better answer.
 
 

Listing the files in a Changeset

I’ve been trying to do this off an on for a while and finally tracked it down…
 
To list the files in a changeset;

C:\Program Files\Microsoft Visual Studio 8\Common7\IDE>tf changeset /i 27880

 

To show the dialog in a separate process so you can carry on using Visual Studio just omit the /i

Passing Exceptions from WCF to Silverlight

After upgrading a Silverlight project to 3 I wondered if the story about passing exceptions from WCF to SL had changed. Previously, because WCF sends fault messages as 500 response codes SL could not see them. However, although I believe this is still true I spotted, Creating and Handling Faults in Silverlight, which explains how to change the end-point behaviour to return faults as 200 codes and therefore suddenly allowing Silverlight to see them. I did have a few teething problems with, mainly to do with me misreading the config soup. One quick gotcha is to remember to refresh your service reference so you can see the new exception, I mean fault, classes.
 
 

Database for Silverlight

Another quick bookmark of a blog that talks about an open source database project that could be ideal for Silverlight out-of-browser applications

Embedded Database Engine for Silverlight Applications

Linq recipe #3, flatten a dictionary of byte arrays into a single byte array

Dictionary<int, byte[]> binaryParts = new Dictionary<int, byte[]>();

// now combine the binary from all the parts by first sorting by key

var flattenedList = binaryParts.OrderBy(p => p.Key).SelectMany(p => p.Value);

byte[] combinedBytes = flattenedList.ToArray();

Linq recipe #2, Convert a CSV string of numbers into an array of numbers

e.g. for every (n) item in the array, apply the Convert function to it and return that as the nth item in the new array

 

int[] strongValues = Array.ConvertAll(csvString.Split(‘,’), n => Convert.ToInt32(n));

Linq recipe #1 combining two enums into a single dictionary

// Using Linq, ignore problems with jaggies

List<int> keys = new List<int> { 1, 2, 3, 4, 5 };           

List<string> data = new List<string> { "a", "b", "c", "d","e" };

 

Dictionary<int,string> combo = (from k in keys

            join d in data on keys.FindIndex(x => x==k) equals data.FindIndex(x2 => x2==d)                           

            select new {Key=k, Value=d} ).ToDictionary(de=>de.Key, de=>de.Value);

foreach (var i in combo)

{

    System.Diagnostics.Debug.WriteLine(i.Key + "," + i.Value);

}

 

// Using lamda expression, doesn’t allow jaggies

Dictionary<int, string> UrisByProject = new Dictionary<int, string>();

List<int> nonZeroProjectIds = new List<int>() { 1, 2, 3, 4,5 };

List<string> urisForTheImage = new List<string>() { "a", "b", "c", "d", "e" };

nonZeroProjectIds.ForEach(p => UrisByProject.Add(p, urisForTheImage[nonZeroProjectIds.FindIndex(t => t == p)]));

foreach (var i2 in UrisByProject)

{

    System.Diagnostics.Debug.WriteLine(i2.Key + "," + i2.Value);

}