Skip to content
Archive of entries posted on August 2010

Modular Silverlight Development, App.xaml, Blend and Resources

As I was working on one of my personal learning projects, I encountered a small problem. The project was Prism based with multiple modules.  I wanted to isolate my resource files, so I created a separate project that included my XAML resources, such as styles.  This approach works just fine by using merged dictionaries in App.xaml:

<Application 
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   x:Class="MyApp.Silverlight.App"
            >
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/MyResources.Silverlight.Common;component/Resources/MyResourcesDictionary.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

 

Now I can reference those resource in my other modules’ screens and use them.  Now back to the original issue.  I can use styles from MyResourceDictionary.xaml, but Blend generates an error for me – it cannot find my resources.  Here is an easy way to overcome this issue.  You have to add the same dictionary into the resources of each screen:  In the example below I am showing resources area for a user control called MySampleView from MyApp module.,

    <MyApp:MySampleView.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/MyResources.Silverlight.Common;component/Resources/MyResourcesDictionary.xaml"/>
            </ResourceDictionary.MergedDictionaries>
            <resource:Resource x:Key="LocalizedResource"/>
        </ResourceDictionary>
    </MyApp:MySampleView.Resources>

As you can see, I combine the styles dictionary with a local resource, in example localized user strings.  You can just as easily add converters, etc… in the same fashion.

There is some cost of course associated with merging dictionaries into each screen, but using Blend is a big benefit.  You can get around this issue by keeping this code commented out, and uncomment when using Blend

There is also another solution, involving having #DEBUG that moves this exact code into code behind of each view.  Of course, this is annoying as well, and this is when the base class for the view comes in.  Here is the code I could add to it to accomplish the same as XAML approach:

#if DEBUG
            var dictionary = new ResourceDictionary() 
                { Source = new Uri("/MyResources.Silverlight.Common;component/Resources/MyResourceDictionary.xaml", UriKind.RelativeOrAbsolute) };
            Resources.MergedDictionaries.Add(dictionary);
#endif

 

This of course underscores the usefulness of having base classes for all your major components, such as views in your applications.  It could be an inconvenience since you cannot just add new user control.  You would have to edit both XAML and code behind to change the inheritance structure of your user controls (views).

<MyApp:MySampleViewBase
   x:Class="MyApp.Views.MySampleView"

public partial class MySampleView : MySampleViewBase, IMySampleView

 

You can further optimize this process by creating custom control templates that would write all this code for you.  This way you would not have to modify the files after creating a new user control.

Thanks.

Post to Twitter

Encryption in Silverlight and .NET Applications

Today I would like to cover a specific use case that came up a few times in Silverlight applications I wrote.  For example, I wand a user to enter some sensitive information, encrypt it in Silverlight client, transfer it over to the server, then decrypt it and perforation some operations on that data.

First step of course is to find sufficiently strong encryption protocol that can be implemented in both Silverlight and .NET and be completely compatible between both run times.  I am going to go for AES encryption.  AES stands for “Advanced Encryption Standard”.  This standard is widely used and approved by US government and standard bodies.  See this article for details.

Luckily, AES encryption is implemented in both Silverlight and .NET run times, using exact same set of classes, primary one being AesManaged class.  My goal is to create a class that I can cross-compile in both runt times, so this comes in super handy.  Second, I wand to implement two methods Decrypt and Encrypt, while paying attention to IDisposable interfaces that the vast majority of classes inside Cryptography namespace implement.  Both static methods take two parameters, input string and a password to be used.  Of course, you have to make sure you use the same password in both methods while encrypting and decrypting information.  You should probably dynamically generate a password during handshake process between a Silverlight client and a .NET server.  I will also use maximum key size and block size of encryption.  I will also dynamically generate key (Key) and initialization vector(IV) properties.    I am going to now spare everyone a number of boring details, and will simply post final version of my utility class:  You can include this class in both .NET and Silverlight project, and even link the physical .cs file from one to the other to ensure that you only have a single version in source control.

Thanks

using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;
 
namespace Encryption
{
    public static class EncryptionUtility
    {
 
        /// <summary>
        /// Encrypt the data
        /// </summary>
        /// <param name="input">String to encrypt</param>
        /// <returns>Encrypted string</returns>
        public static string Encrypt(string input, string password)
        {
 
            byte[] utfData = UTF8Encoding.UTF8.GetBytes(input);
            byte[] saltBytes = Encoding.UTF8.GetBytes(password);
            string encryptedString = string.Empty;
            using (AesManaged aes = new AesManaged())
            {
                Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(password, saltBytes);
 
                aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
                aes.KeySize = aes.LegalKeySizes[0].MaxSize;
                aes.Key = rfc.GetBytes(aes.KeySize / 8);
                aes.IV = rfc.GetBytes(aes.BlockSize / 8);
 
                using (ICryptoTransform encryptTransform = aes.CreateEncryptor())
                {
                    using (MemoryStream encryptedStream = new MemoryStream())
                    {
                        using (CryptoStream encryptor = 
                            new CryptoStream(encryptedStream, encryptTransform, CryptoStreamMode.Write))
                        {
                            encryptor.Write(utfData, 0, utfData.Length);
                            encryptor.Flush();
                            encryptor.Close();
 
                            byte[] encryptBytes = encryptedStream.ToArray();
                            encryptedString = Convert.ToBase64String(encryptBytes);
                        }
                    }
                }
            }
            return encryptedString;
        }
 
        /// <summary>
        /// Decrypt a string
        /// </summary>
        /// <param name="input">Input string in base 64 format</param>
        /// <returns>Decrypted string</returns>
        public static string Decrypt(string input, string password)
        {
 
            byte[] encryptedBytes = Convert.FromBase64String(input);
            byte[] saltBytes = Encoding.UTF8.GetBytes(password);
            string decryptedString = string.Empty;
            using (var aes = new AesManaged())
            {
                Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(password, saltBytes);
                aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
                aes.KeySize = aes.LegalKeySizes[0].MaxSize;
                aes.Key = rfc.GetBytes(aes.KeySize / 8);
                aes.IV = rfc.GetBytes(aes.BlockSize / 8);
 
                using (ICryptoTransform decryptTransform = aes.CreateDecryptor())
                {
                    using (MemoryStream decryptedStream = new MemoryStream())
                    {
                        CryptoStream decryptor = 
                            new CryptoStream(decryptedStream, decryptTransform, CryptoStreamMode.Write);
                        decryptor.Write(encryptedBytes, 0, encryptedBytes.Length);
                        decryptor.Flush();
                        decryptor.Close();
 
                        byte[] decryptBytes = decryptedStream.ToArray();
                        decryptedString = 
                            UTF8Encoding.UTF8.GetString(decryptBytes, 0, decryptBytes.Length);
                    }
                }
            }
 
            return decryptedString;
        }
    }
}

Post to Twitter

XAML Intellisense Stops Working in Visual Studio 2010

Today as I was working on a Silverlight application in Visual Studio 2010, XAML Intellisense just stopped working for me.  Quick internet search yielded no useful results, so I was to figure this out on my own.  Just to test I created a brand new application, and Intellisense was fine there.  Logical answer was that there was something wrong with my project.  I re-created the project, and slowly retraced my steps, testing XAML Intellisense  after each step.  The feature broke again as soon as I added a reference to  third party library I downloaded off the internet.  Something wrong with a file, obviously.  What I saw is that the DLL in question was blocked by Windows security.  I unblocked by right-clicking on the file in Windows explorer, going to properties and clicking Unblock button.

The package that I downloaded included many files, and I really hated to go through each one. Next internet search yielded a great solution from SysInternals.  You can download it here.  Once I got streams utility, I ran it on entire folder, and voila – Intellisense was back.  The command line is “streams –s –d ‘Folder with DLLs to Unblock’”, in my case “streams –s –d “c:\ThirdParty””

So, my research solved two problems for me – missing XAML Intellisense  and ability to unblock multiple files which is something I wanted to find an answer to a while ago,

Post to Twitter