The ramblings of web developer Beau Brownlee

Archive for the ‘ C# ’ Category

BouncyCastle is a really powerful encryption library that most Java developers will know about. It has been a fundamental library for many years now. They also have an inter-operable library for C# that can be compiled in the full .net framework and Silverlight. Most .net developers use the CNG library wrapper class library which has advantages such as some FIPS certifications. However, that is only implemented as of Vista and above and is not implemented in platforms such as Silverlight or any of the Mono or MonoTouch frameworks so there are still compelling reasons to use BouncyCastle in C#. In an ideal world you should be able to encrypt/decrypt across all libraries and, as it turns out, you can. Ok, I’ll shut up and get to the code. The following is an example of using BouncyCastle in Java, C# and an equivalent example in .net CNG:

// C# BouncyCastle
 
public static byte[] Encrypt(byte[] input, byte[] baseKey, byte[] HMACKey)
        {
            byte[] cryptKey = new byte[32];
            // Generate initialization vector
            byte[] iv = GenerateCryptoRandomByteArray(16);
 
            Array.Copy(baseKey, 0, cryptKey, 0, 32);
 
            ParametersWithIV key = new       ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES", cryptKey), iv);
 
            IBufferedCipher outCipher = CipherUtilities.GetCipher(NistObjectIdentifiers.IdAes256Cbc.Id);
 
            outCipher.Init(true, key);
 
            byte[] bytes = outCipher.DoFinal(input);
 
            byte[] hmac = HMACSignBytes(HMACKey, bytes);
 
            byte[] result = new byte[bytes.Length + iv.Length + hmac.Length];
 
            Buffer.BlockCopy(bytes, 0, result, 0, bytes.Length);
            Buffer.BlockCopy(iv, 0, result, bytes.Length, iv.Length);
            Buffer.BlockCopy(hmac, 0, result, bytes.Length+iv.Length, hmac.Length);
 
            return result;
        }
 
public static byte[] HMACSignBytes(byte[] Key, byte[] Data)
        {
            HMac hmac = new HMac(new Sha512Digest());
 
            byte[] resBuf = new byte[hmac.GetMacSize()];
 
            hmac.Init(new KeyParameter(Key));
            hmac.BlockUpdate(Data, 0, Data.Length);
            hmac.DoFinal(resBuf, 0);
 
            return resBuf;
        }
 
public static byte[] GenerateCryptoRandomByteArray(int length)
        {
            byte[] buffer = new byte[length];
            SecureRandom sr = new SecureRandom();
 
            sr.NextBytes(buffer, 0, length);
 
            return buffer;
        }
// Java BouncyCastle
    public static byte[] Encrypt(byte[] input, byte[] baseKey, byte[] HMACKey) throws EncryptionException
     {
    	try
    	{
         // Generate initialization vector
         byte[] iv = EncryptionEngine.GenerateCryptoRandomByteArray(16);
 
         Key key = new SecretKeySpec(baseKey, "AES");
 
         Cipher outCipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
 
         outCipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
 
         byte[] bytes = outCipher.doFinal(input);
 
         byte[] hmac = HMACSignBytes(HMACKey, bytes);
 
         byte[] result = new byte[bytes.length + iv.length + hmac.length];
 
         System.arraycopy(bytes, 0, result, 0, bytes.length);
         System.arraycopy(iv, 0, result, bytes.length, iv.length);
         System.arraycopy(hmac, 0, result, bytes.length+iv.length, hmac.length);
 
         String hexhmac = new String(Hex.encode(hmac));
         String hexiv = new String(Hex.encode(iv));
         String hexcipher = new String(Hex.encode(bytes));
 
         return result;
    	}
    	catch(Exception ex)
    	{
    		throw new EncryptionException(ex);
    	}
     }
 
	public static byte[] GenerateCryptoRandomByteArray(int length)
    {
        byte[] buffer = new byte[length];
        SecureRandom sr = new SecureRandom();
 
        sr.nextBytes(buffer);
 
        return buffer;
    }
 
	public static byte[] HMACSignBytes(byte[] Key, byte[] Data)
    {
        HMac hmac = new HMac(new SHA512Digest());
        byte[] resBuf = new byte[hmac.getMacSize()];
 
        hmac.init(new KeyParameter(Key));
        hmac.update(Data, 0, Data.length);
        hmac.doFinal(resBuf, 0);
 
        return resBuf;
    }
// C# CNG
public static byte[] Encrypt(byte[] srcBytes, byte[] baseKey, byte[] HMACKey)
        {
            // Encryption will be performed using memory stream.
            MemoryStream memoryStream = new MemoryStream();
 
            // Let's make cryptographic operations thread-safe.
            lock (lockObj)
            {
                byte[] IV = EncryptionEngine.GenerateIV();
                ICryptoTransform encryptor = BuildEncryptor(baseKey, IV);
 
                // To perform encryption, we must use the Write mode.
                CryptoStream cryptoStream = new CryptoStream(
                                                   memoryStream,
                                                   encryptor,
                                                   CryptoStreamMode.Write);
 
                // Start encrypting data.
                cryptoStream.Write(srcBytes, 0, srcBytes.Length);
 
                // Finish the encryption operation.
                cryptoStream.FlushFinalBlock();
 
                // Move encrypted data from memory into a byte array.
                Byte[] cipherTextbyte = memoryStream.ToArray();
 
                List<byte> cipher_IV_HMAC = new List<byte>();
                cipher_IV_HMAC.AddRange(cipherTextbyte);
                cipher_IV_HMAC.AddRange(IV);
                cipher_IV_HMAC.AddRange(HMACSignBytes(HMACKey, cipherTextbyte));
 
                // Close memory streams.
                cryptoStream.Close();
                memoryStream.Close();
                encryptor.Dispose();
                return cipher_IV_HMAC.ToArray();
            }
        }
 
public static byte[] GenerateIV()
        {
            using (AesCryptoServiceProvider am = new AesCryptoServiceProvider())
            {
                am.GenerateIV();
 
                return am.IV;
            }
        }
 
public static byte[] HMACSignBytes(byte[] Key, byte[] Data)
        {
            using (FIPSHmacSha512 hmac = new FIPSHmacSha512(Key))
            {
                byte[] HashValue = hmac.ComputeHash(Data);
 
                hmac.Dispose();
                return HashValue;
            }
 
        }
 
internal class FIPSHmacSha512 : System.Security.Cryptography.HMAC
{
    public FIPSHmacSha512(byte[] key)
    {
        if (key == null)
            throw new ArgumentNullException("key");
 
        HashName = "System.Security.Cryptography.SHA512CryptoServiceProvider";
        HashSizeValue = 512;
        BlockSizeValue = 128;
        Key = key;
    }
}

“Ok,, what the heck am I looking at?!?!?”. Well here’s what happens, each one of these functions is ultimately doing the same 3 things:

  1. Generating a Nonce (Number Used Only Once) for the initialization vector that AES 256 requires
  2. Encrypt the data
  3. Sign the cipher text with an HMAC function

First, the initialization vector is required as we are using AES256 CBC block mode I won’t go into more detail on the specifics of why we use CBC but suffice it to say, CBC is much stronger than some of the other block modes such as ECB especially if you need to encrypt the same data more than one time with the same secret key. This block mode requires an initialization vector that uses a crypto pseudo random function. There are many people who have used linear congruential random generators by mistake instead of a strong random generator such as earlier versions of Kerberos. Don’t make that mistake! If an attacker can predict the next number in a random number used, it weakens if not completely compromises the cipher strength.

Next, we encrypt the data. Woo hoo! A couple things to note, we are using PKCS7Padding. All three functions must use this padding to be inter-operable. This helps to reduce the predictability of the plaintext.

Next up, we sign the cipher with an HMAC function. Why do we do this? Well as it turns out there even though a cipher may not be decrypted, it can be modified. There are several possible attacks against ciphers that can modify the original plain text so we use an HMAC function to sign the cipher. This means that during our decryption we must verify the HMAC signature with the original HMAC key to verify that the original cipher has not been tampered with in any way. Finally we just append all the data together in one big cipher package that we can pull apart and decrypt with later.

So to decrypt… well.. how about we just look at code…

// C# BouncyCastle
public static byte[] Decrypt(byte[] input, byte[] baseKey, byte[] HMACKey)
        {
 
            byte[] hmac = new byte[64];
            byte[] iv = new byte[16];
            byte[] cipher = new byte[input.Length - 16 - 64];
            byte[] cryptKey = new byte[32];
 
            Array.Copy(input, input.Length - 64, hmac, 0, 64);
            Array.Copy(input, input.Length - 64 - 16, iv, 0, 16);
            Array.Copy(input, 0, cipher, 0, input.Length - 16 - 64);
            Array.Copy(baseKey, 0, cryptKey, 0, 32);
 
            string hexkey = Hex.ToHexString(baseKey);
            string hexhmackey = Hex.ToHexString(HMACKey);
            string hexhmac = Hex.ToHexString(hmac);
            string hexiv = Hex.ToHexString(iv);
            string hexcipher = Hex.ToHexString(cipher);
 
            if (!HMACVerifyBytes(HMACKey, hmac, cipher))
            {
                throw new Exception("HMAC is invalid");
            }
 
            ParametersWithIV key = new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES", cryptKey), iv);
 
            IBufferedCipher inCipher = CipherUtilities.GetCipher(NistObjectIdentifiers.IdAes256Cbc.Id);
 
            inCipher.Init(false, key);
 
            return inCipher.DoFinal(cipher).ToArray();
        }
 
public static bool HMACVerifyBytes(byte[] Key, byte[] HMACSignature, byte[] Data)
        {
            byte[] signature = HMACSignBytes(Key, Data);
 
            if (signature.SequenceEqual(HMACSignature))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
public static byte[] Decrypt(byte[] input, byte[] baseKey, byte[] HMACKey) throws EncryptionException
     {
    	try
    	{
         byte[] hmac = new byte[64];
         byte[] iv = new byte[16];
         byte[] cipher = new byte[input.length - 16 - 64];
 
         System.arraycopy(input, input.length - 64, hmac, 0, 64);
         System.arraycopy(input, input.length - 64 - 16, iv, 0, 16);
         System.arraycopy(input, 0, cipher, 0, input.length - 16 - 64);
 
         if (!HMACVerifyBytes(HMACKey, hmac, cipher))
         {
             throw new Exception("HMAC is invalid");
         }
 
         Key key = new SecretKeySpec(baseKey, "AES");
 
         Cipher inCipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
 
         inCipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
 
         byte[] results = inCipher.doFinal(cipher);
 
         return results;
    	}
    	catch(Exception ex)
    	{
    		throw new EncryptionException(ex);
    	}
     }
 
public static Boolean HMACVerifyBytes(byte[] Key, byte[] HMACSignature, byte[] Data)
    {
        byte[] signature = HMACSignBytes(Key, Data);
 
        if (Arrays.areEqual(signature, HMACSignature))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
// C# CNG
public static byte[] Decrypt(byte[] srcBytes, byte[] baseKey, byte[] HMACKey)
        {
            List<byte> SourceBytes = new List<byte>(srcBytes);
 
            //Extract the cipher, initialization vector and the hmac
            byte[] cipher = SourceBytes.GetRange(0, srcBytes.Length - 80).ToArray();
            byte[] IV = SourceBytes.GetRange(srcBytes.Length - 80, 16).ToArray();
            byte[] HMAC = SourceBytes.GetRange(SourceBytes.Count - 64, 64).ToArray();
 
            // Validate HMAC
            if (!HMACVerifyBytes(HMACKey, HMAC, cipher))
            {
                throw new Exception("HMAC is invalid");
            }
 
            // Encryption will be performed using memory stream.
            MemoryStream memoryStream = new MemoryStream(cipher);
 
            // Let's make cryptographic operations thread-safe.
            lock (lockObj)
            {
                ICryptoTransform decryptor = BuildDecryptor(baseKey, IV);
 
                // To perform encryption, we must use the Write mode.
                CryptoStream cryptoStream = new CryptoStream(
                                                   memoryStream,
                                                   decryptor,
                                                   CryptoStreamMode.Read);
 
                byte[] source = new byte[memoryStream.Length];
                // Start decrypting data.
                int byteCount = cryptoStream.Read(source, 0, source.Length);
 
                byte[] ReturnSource = new byte[byteCount];
                Buffer.BlockCopy(source, 0, ReturnSource, 0, byteCount);
 
                // Close memory streams.
                cryptoStream.Close();
                memoryStream.Close();
                decryptor.Dispose();
                return ReturnSource;
            }
        }
 
public static bool HMACVerifyBytes(byte[] Key, byte[] HMACSignature, byte[] Data)
        {
            using (FIPSHmacSha512 hmac = new FIPSHmacSha512(Key))
            {
                byte[] HashValue = hmac.ComputeHash(Data);
 
                hmac.Dispose();
                return HMACSignature.SequenceEqual(HashValue);
            }
        }

The process in reverse. We simple take apart that which we have created and decrypt it. It starts by verifying that the signature is the same so we know that the cipher has not been tampered with. Then we extract the IV and use that as well as the secret key to decrypt our data and return our original plaintext, or in this case, a byte array.

 
Friday, January 7th, 2011

One powerful feature of silverlight is the ability to quickly and easily build animations into your application. Animations are typically built out using a Storyboard control either in your XAML or programatically in C#. Your storyboard will contain an animation and that animation will be applied to an element. Animations can be DoubleAnimation, ColorAnimation or a PointAnimation. Today we will just focus on the DoubleAnimation.

Double Animations

A DoubleAnimation is simply a double that is either incremented or decremented and is applied to a property. So before we get any further, lets take a look at what it can do:

Just show it to me

As you can see this is smoothly animated to show or hide a simple gray box. The box is just a stack panel that could potentially hold more elements. Here’s the code:

XAML

<UserControl x:Class="SilverlightApplication1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    <Grid x:Name="LayoutRoot" Background="White">
        <Canvas Background="White" Margin="0,0,34,108" x:Name="mycanvas">
            <Canvas.Resources>
                <Storyboard x:Name="ShowStoryboard">
                    <DoubleAnimation
                        Storyboard.TargetName="mystackpanel"
                        Storyboard.TargetProperty="(Canvas.Top)"
                        From="-50"
                        To="0"
                        Duration="0:0:.5"
                    >
                        <DoubleAnimation.EasingFunction>
                            <BackEase Amplitude=".5" EasingMode="EaseOut" />
                        </DoubleAnimation.EasingFunction>
 
                    </DoubleAnimation>
                </Storyboard>
 
                <Storyboard x:Name="HideStoryboard">
                    <DoubleAnimation
                        Storyboard.TargetName="mystackpanel"
                        Storyboard.TargetProperty="(Canvas.Top)"
                        From="0"
                        To="-50"
                        Duration="0:0:.5">
                        <DoubleAnimation.EasingFunction>
                            <BackEase Amplitude=".5" EasingMode="EaseIn" />
                        </DoubleAnimation.EasingFunction>
                    </DoubleAnimation>
                </Storyboard>
 
            </Canvas.Resources>
            <StackPanel Canvas.Top="-50" Height="50" Width="640" VerticalAlignment="Top" x:Name="mystackpanel" Background="Gray">
            </StackPanel>
            <Button Content="Show" Height="23" Name="button1" Width="75" Click="button1_Click" Canvas.Left="20" Canvas.Top="137" />
            <Button Canvas.Left="110" Canvas.Top="137" Content="Hide" Height="23" Name="button2" Width="75" Click="button2_Click" />
        </Canvas>
    </Grid>
</UserControl>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
 
namespace SilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }
 
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            if (Canvas.GetTop(mystackpanel) == -50)
            {
 
                ShowStoryboard.Begin();
            }
        }
 
        private void button2_Click(object sender, RoutedEventArgs e)
        {
            if (Canvas.GetTop(mystackpanel) == 0)
            {
                HideStoryboard.Begin();
            }
 
        }
    }
}

Explanation

As you can see in the XAML code we have 2 storyboards. One to show the gray square and 1 to hide the gray square. The only thing we have in our C# code is to simply start each animation if the animation is shown or hidden. Notice that our stack panel is in a canvas to move it precisely where we want it. With a DoubleAnimation there are 5 major pieces:
#1 Set the Target Name: The target name is the ID of the element we want to animate.
#2 Set the target property: The target property is the property we want to set the double property to. In this case it is (Canvas.Top) <- note the parenthesis when you have a multipart property.
#3 Set the From property: The from property is the starting value.
#4 Set the To property: The to property is the ending value.
#5 Set the duration: Hours:Minutes:Seconds.
You will also notice that we also have a nested EasingFunction. We will go over the easing functions later in the series.

The end?

This is just to ‘wet your whistle’ and show you a basic animation that silverlight can do. I will be posting up more on silverlight animations soon.

 
Saturday, September 11th, 2010

Just messing around with my new FEZ Domino board and I thought I’d post up a quick tutorial on how to use a motion sensor with your board. First thing you will want to understand is interrupt ports. An interrupt port is a port that is listening and waiting for something to happen. For instance voltage levels going up or going down. In this tutorial I use a motion sensor that I got from parallax here. This is a very basic sensor that has voltage tolerance of 3-5v and has one pin that outputs high or low voltage levels. High means its sensed motion. The next part of this project involves a small speaker that outputs a tone to let you know its sensed motion. Nothing loud or anything but just for demonstration purpose. You can get the driver for the tone generation here: http://www.tinyclr.com/downloads/Component/FEZ_Components_Piezo.cs. So here’s the code:

#region motion sensor
            Thread.Sleep(30000);
 
            tone = new FEZ_Components.Piezo(FEZ_Pin.PWM.Di5);
            InterruptPort motion = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.Di1, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeHigh);
            motion.OnInterrupt += new NativeEventHandler(motion_OnInterrupt);
 
            Thread.Sleep(-1);
#endregion
 
 
static void motion_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            tone.Play(400, 1000);
        }

To see more about how to hook the hardware up check out the video:

There needs to be about a thirty second ‘warm up’ time as the sensor gets to know its surroundings and after that the sensor will be ready to be connected to the interrupt port. The interrupt port will listen for the voltage levels to go up and when they do it will play the tone.

 
Thursday, September 9th, 2010

So the issue that I ran into recently is that I’m getting data in an observable object list and then getting an updated list. I need to be able to compare each object in the list to see if it has been updated or not. The problem is that I have a lot of properties in each object and I had several object lists which I needed to compare. The solution I wanted involves IComparable. This is a very simple interface that implements CompareTo method only. CompareTo receives an object and returns an integer. This interface is used for comparing and doing things like sorting in arrays but in this case all I need to check for is if the CompareTo returns 0 (equals) or anything but 0 (not equal).

Another problem is that to implement this function you have to write all the checking code yourself and if you have alot of properties to check you have to do that manually somehow. I wanted something to simply check to see if all properties in the current object and the object passed in through CompareTo function were equal. Here is some code to do that:

// Implement IComparable interface and use this as your function
#region IComparable Members
            public int CompareTo(object obj)
            {
                int return_value = 0;
 
                if (obj.GetType() == this.GetType())
                {
                    Type t = this.GetType();
 
                    foreach (PropertyInfo p in t.GetProperties())
                    {
                        Type t2 = obj.GetType();
 
                        object prop1_value = p.GetValue(this, null);
                        object prop1_name = p.Name;
 
                        foreach (PropertyInfo p2 in t2.GetProperties())
                        {
                            object prop2_value = p2.GetValue(obj, null);
                            object prop2_name = p2.Name;
 
                            if (prop1_name == prop2_name)
                            {
                                if (prop1_value != null && prop2_value != null)
                                {
                                    if (!prop1_value.Equals(prop2_value))
                                    {
                                        return_value++;
                                    }
                                }
                                break;
                            }
                        }
                    }
                }
                else
                {
                    return_value++;
                }
                return return_value;
            }
            #endregion

This uses system.reflection to iterate through the properties in both objects comparing the values using the ‘Equals’ method to validate the values are the same. If the properties are not the same the return_value is incremented and more than 0 is returned. This is pretty generic and should work with most classes you build. You may need to add in an if statement to filter out properties you do not wish to include in this comparison as this just checks all properties in the object.

 
Wednesday, June 2nd, 2010

One of the things I needed recently is a simple way to have a textbox that had a watermark in it. Apparantly SilverLight 4 provides it,,, and it doesn’t provide it. Check this post out. I really couldn’t help but laugh when I saw this. ‘Do not use in a Silverlight 4 application.’ and at the same time the supported version is only Silverlight 4. Aaah yes, well the only other solution is to use a watermark textbox someone else has created or to make your own. I opted to make my own. Before we get into the code here it is:

This just gives you a basic idea of what you can do. The first textbox is the user control that has watermark capabilities. If you click on the water marked textbox it will clear it out and be ready for input. If you do not type in any text and leave it blank and click on the second textbox it will replace the watermark. If you click the ‘Get Text’ button it will show blank because you do not want the watermark to count as valid text. If you click ‘Set Text’ it will programatically set the text in the textbox and you will notice that the watermark disappears.

(more…)

 
Thursday, May 27th, 2010

Reading an xml file is something that every developer has to do at some point (if not regularly). XML protocol is extremely prevalent across all technologies which makes it important to understand how to parse it. Sivlerlight exposes System.XML.Linq namespace that has all the needed classes to use Linq to query your XML to get the node/s that you need.

Always Starts with the Document

As with every XML reader you start out by creating an instance of the document and then filling it with the XML file’s data. In this case Silverlight provides ‘XDocument’ class to instantiate the document object and then the ‘Load’ method to read the data into the object. Then once we’ve loaded the object with data then we can run a traditional Linq query on the data.

Test Case

So lets run through a test case. Lets say we have a configuration file in which we want to determine what logo to display based on the url that called it. So here is our example xml:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <Logos>
    <Logo url="url1">
      <LoginWindowLogo>/namespace;path/img1.png</LoginWindowLogo>
    </Logo>
    <Logo url="url2">
      <LoginWindowLogo>/namespace;path/img2.png</LoginWindowLogo>
    </Logo>
  </Logos>
</configuration>

And here is the C# code to read it:

XDocument document = XDocument.Load("Config.xml");
 
            var images = (from e in document.Descendants("Logo")
                          where e.Attribute("url").Value == App.Current.Host.Source.Host
                          select new
                          {
                              LoginWindowLogo = e.Element("LoginWindowLogo").Value,
                          }).FirstOrDefault();
 
            if (images != null)
            {
                loginwindowlogopath = images.LoginWindowLogo;
            }

App.Current.Host.Source.Host is the property that gives you the current apps domain, the function ‘FirstOrDefault’ get the results and turn it into an object that just has the properties selected.

 
Wednesday, May 26th, 2010

An advantage of using Silverlight is the fact that the entire app is cached locally. While this may take a while to download initially, after everything is downloaded the app runs very very fast and only requires you download information asynchronously from a web service. The only problem is, what if you make changes? Since the app is cached those changes are sometimes not downloaded automatically. So what to do? Lars Holm Jensen wrote a nifty little post that shows how you can determine when the last time the silverlight package was was deployed by reading the datetime stamp on the ‘xap’ file. Just in case you didn’t click on the link, here’s the code:

<object id="Xaml1" data="data:application/x-silverlight-2," type="application/x-silverlight-2"
width="100%" height="100%">
<%
string orgSourceValue = @"ClientBin/SilverlightApp.xap";
string param;
 
if (System.Diagnostics.Debugger.IsAttached)
param = "<param name=\"source\" value=\"" + orgSourceValue + "\" />";
else
{
string xappath = HttpContext.Current.Server.MapPath(@"") + @"\" + orgSourceValue;
 
DateTime xapCreationDate = System.IO.File.GetLastWriteTime(xappath);
param = "<param name=\"source\" value=\"" + orgSourceValue + "?ignore="
+ xapCreationDate.ToString() + "\" />";
}
 
Response.Write(param);
%>
 
<param name="onError" value="onSilverlightError" />

The ‘if’ statement checks to see if your debugging. If you are, then grab the latest/greatest. If not, then it’s assumed that you are in production mode and then it checks to see if you have the latest and greatest. If you don’t, then download the latest version. Thanks Lars!

 
Wednesday, May 26th, 2010

One very important task you have as a developer is to keep track of errors. Errors you ask? ‘Errors’? ‘Not me, I write bug free code!’. Ok Mr. Programming God, but for the rest of us mortals, we have to do something to keep track of all the human errors that get embedded into our code. There are many different ways to store these errors, some people do it in flat files, others in databases. We won’t be talking about where to store these errors, just how to get them from silverlight.

The problem

Web applications have always presented a particular problem when it comes to catching errors and logging them in a central place. First, with Javascript it is difficult to know when an error has occurred and hasn’t been caught already and if so, it’s difficult to do anything after that as many javascript errors will break the app entirely and not run anymore code.

The Solution… A Solution

Silverlight attempts to simplify this process by having a central place to catch any unhandled exceptions and then do something with them. You can catch them in the App.xaml.css file. Here is an example:

private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
    {
      //Ignores logging if your debugging
      if (!System.Diagnostics.Debugger.IsAttached)
      {
        /*TODO: Some method to save the 
           the error to a file or database by using
           e.ExceptionObject.Message, e.ExceptionObject.StackTrace
        */
        e.Handled = true;
        ChildWindow errorWin = new ErrorWindow("Error", "An Error has been logged"));
        errorWin.Show();
      }
    }

Does this mean that we don’t need to do any try/catches? No, we still need to handle errors and do something with them, but in the event that we miss an error, it will be caught here and logged so that we can more easily debug the released code.

 
Tuesday, December 1st, 2009

Jumploader is a very cool very powerful uploading agent. It is a java applet that runs in your browser that allows you to upload very large files by breaking them up into ‘partitions’ (small sections of a file). It has other neat features such as drag and drop files, image editing, meta data forms and file compression. The responsibility on the developers side is handling the file uploads with server side scripting of some kind. It works with pretty much any server side language such as PHP, .net, Python etc… Anything that can run in a web server and write to a file stream. I’ve worked with this recently in .net. There is an open source example of how to use Jumploader with C# on their website originally written by Michael Wright. It isn’t updated however and it was missing some key features that I needed such as examples on how to handle the ‘resume’ feature, allowing for the meta data forms and a few other things. I made several updates to the original code and have started an open source project on Google Project. You can visit the project at http://code.google.com/p/jlnetwrapper/. I will be updating this periodically and am always happy for other contributions to this project as well.

 
Thursday, November 12th, 2009

I have recently been using LINQ to accomplish much of my data abstraction and have found it very useful for building a robust ASP.Net application. Ultimately what LINQ to SQL does is it translates your C# code into a SQL query and returns an object or an object list instead of a dataset. This can be much easier to deal with than a dataset. I have run into a couple things that I didn’t expect so I thought I’d share. (more…)