Dancing With Dot Net

Exploring .NET Features

Dancing With Dot Net

Animating a Cutout versus Animating an Image with a Transparent Background in Silverlight

In my prior blog entry, I had created a cutout of an image and animated it in a Silverlight application. I had speculated that I did not know if there was any perceptible performance difference between animating a cutout using the imagebrush or using an image with a transparent background. Since the cutout consists of a path with a lot of vertices (hundreds), I felt that this might be harder to animate than a simple png file with a transparent background. This blog will attempt to answer that question.

Car

The first problem I encountered was surprisingly difficult to solve. I needed a png with an image with a transparent background. I already had my cut out of a car image in XAML path mini-language. The car was a png image. All I needed to do was take the car image file and make the background transparent (this is a feature the png format supports). So I loaded the image up in MS Paint and sought for hours to make the background transparent with no such luck. Paint doesn’t support doing that. Eventually, I ended downloading Adobe Photoshop (about a gigabyte of download). After downloading Photoshop, it still took me another hour or so to figure out how to make the background transparent. It was not easy and intuitive, so beware. But I then had a problem in that part of my transparent background was ghosting up artifacts. I was not able to fix this problem.

So now, I was ready to set up a race between my transparent png image and my cutout image and see if there was any differences I could detect in the rendering. My cutout image consisted of a path I created with the “squiggle” tool in Microsoft Word as I traced the outline of the image with my mouse. Please refer to my prior blog for how I did that. The path consists of a lot of cubic bezier curves (path mini-language ‘C’). At first, I used one storyboard and one DoubleAnimation for each car. In addition, I added an interesting background I borrowed from Starcraft II. This as it turned out, was difficult to do as the “PrintScreen” function seems to be disabled in the game. I also used a random number generator to vary the speed of the car (so I could have a winner). An easing function was added to simulate acceleration of the car. My code looked similar to the following.

My test with the two test cars showed no difference in animation rendering (no flicker or jerkiness). So I added 6 more cars (three transparent images and three cutout images) and ran my test again. I could discern no difference in animation rendering. So, my suspicion that the cutout image may not render as smoothly as transparent background image proved unfounded. Of course with more cars, I might have observed a difference, but I am fairly assured now that I shouldn’t worry about the performance difference in using either approach.

How to Create Cutout Images for WPF/Silverlight

Sometimes we want to add cutout images to our WPF or Silverlight applications. These cutout images are images with an irregular shape (the shape of the object in the picture). For example, let’s say we want to make a cutout of the image of the new 2010 camaro in the accompanying image.

But before we can add animation and other cutesy effects to our cutout image, we need the irregular shaped visual object. There are two approaches to achieve this effect in WPF and Silverlight. First, we can take a rectangular image and set the external portions of the image to a transparent color in a graphics editor (like paint). This creates a visual cutout image that we can then manipulate. This image looks like the car on the left.  Another approach is to create an outline of the image and then use an ImageBrush to fill the outline. This is the approach we will investigate in this blog article.

The problem is how to create the shape outline in XAML path mini-language. This can be achieved easily with Expression Blend, a graphics-design product made by Microsoft that can output a traced outline of the car in XAML. But Expression Blend is packaged with Expression Studio which currently sells for around $600. Another option is that we create the XAML path by hand. This is tedious and time-consuming. Fortunately, we have a third option. We can insert the image in a Word document. We can then trace the car outline using the drawing tools in Microsoft Word. After tracing the outline, we save the Word document in XPS format. XPS (XML Paper Specification) is a Microsoft standard for producing fixed, print-ready documents (similar to a PDF file). Under the covers, this standard uses XAML! Surprise, surprise!  It is then no problem to drill down into XPS file (it is really simply a zip file) and extract our outline tracing as XAML path mini-language and copy and paste it into our application. 

You can first of all crop the image in your favorite image editor, so that the object is fully contained in the rectangle and the rectangle is at it's smallest size.  We do this so that when we paint the image in the path object in XAML, the image is centered in the outline.  Next, open up Microsoft Word with a new document. On the Insert menu, we add a new picture and select our image file.  Now comes the tricky part. We click on ‘Shapes’ on the Insert ribbon menu. The dropdown shows a number of drawing tools. Select the scribble pen. This pen will allow you to very carefully trace the outline of the object in your image. After tracing the outline, the image may be cutout. Ignore this and save the file in XPS format from the save as menu item.

Now comes the tricky part. We click on ‘Shapes’ on the Insert ribbon menu in Visual Studio. The dropdown shows a number of drawing tools. Select the scribble pen. This pen will allow you to very carefully trace the outline of the object in your image. After tracing the outline, the image may be cutout. Ignore this and save the file in XPS format from the 'Save As' menu item.

We need to drill down into the directory structure of the XPS file, but
Windows Explorer is unhelpful. This file is really just a zip file (wait! … I’m sensing a theme here….) We need to change the file extension to ‘zip’, so that we can work with it as a zip folder. I don’t know an easy way to do this, other than from a command line prompt. After renaming the file, we can drill down using Windows Explorer to the XAML file we need.  Examing the zip folder contents, we notice a number of folders.  The file we need is in the Documents folder.  In the Documents folder, each page appears as a number corresponding to the page number.  We want the folder named "1".  In the "1" folder, there are subfolders.  We want to drill down into the Pages folder.  Here there will be a file named "1" of type "FPAGE".  Double-click on this file and it should open up in notepad.  And we discover that this "FPAGE" type document contains XAML!  Examine the XAML text and find the Path tag with the XAML path mini-language statements.  We are going to copy and paste this tag and it's contents to your WPF or Silverlight application.

We are now almost done. Go to the WPF or Silverlight project where you want to use your cutout image. You will need to insert a Path tag in your image where you want the cutout to be. Paste the Path tag from the FPAGE XAML file. Eliminate the extraneous attributes from the Path tag or modify them appropriately. You will need to add the cropped image of your object to your solution project. You should verify that the Build action for the image is of type “Resource”. This means it will be embedded in the assembly. Finally, you need to create an ImageBrush object in XAML that has the cropped image set to the ImageSource property. The ImageBrush object will be set to the Fill property of the Path object in XAML. You can use the long syntax for this or store the ImageBrush as a resource for the window. That is what I have done as shown in the image below.

We now have an irregular shaped image that we can animate or add other effects to. In future, blogs we will compare the performance of animating our cutout image versus animating our car as a rectangle with the outer part of the outline set to a transparent color.

How To Encrypt The .NET Config File

How To Encrypt The .NET Config File

Both website applications and client applications allow the application to store sensitive information in an XML configuration file. This sensitive information could be database connection strings or user credentials. The .NET framework allows us to encrypt configuration sections with tags <appSettings>, <connectionStrings>, <identity>, and <sessionState>. In most deployment environments, these configuration files can remain safely hidden and inaccessible. However, it is possible to encrypt these files for added protection. We will use the DPAPI (Data Protection Application Programming Interface) provided by the .NET framework. You can also use RSA as the encryption algorithm, but we won’t be demonstrating using RSA encryption. As an added wrinkle, the encrypted config file may not reside in the project that contains your presentation logic. So in this example, we will create a two project solution with a Windows Forms presentation project and a Data Access project. The Data Access project config file will contain a database connection string with possibly a username and password which we desire to encrypt.

There are a number of tricky issues that come up during the implementation. The first tricky issue is the timing of when we encrypt the config file. During development, we want the information to remain available and unencrypted in Visual Studio. During build-time, we want to encrypt the config file and place it in the appropriate deployment directory. BUT, we need to encrypt the config file by running .NET code, which implies that we can’t do it at build-time (unless you are more clever than I am). The easiest solution to this conundrum, is to run our application once after compiling. We can then safely deploy it with the config files encrypted. Our code will have the logic necessary to detect if the config file is not encrypted, and to then encrypt it. After that, the application deliverables should only include the encrypted config file. There is only one problem with this scenario. The encryption algorithm uses the machine key. That means that we can’t ship encrypted config files from the development machine to the deployment machines and expect the deployment machines to be able to decrypt the encrypted config files.So….. we will have to deploy the unencrypted config files to the deployment machines. Once the application runs, the config files will be encrypted. Whether this is an acceptable solution depends on your deployment scenario. RSA encryption has similar problems.

The first thing we need to do is create two projects in Visual Studio. The first project will be a Windows Forms project that I named ‘EncryptConfig’.   The other project will be a class library named ‘DataAccess’. Now we can create an application scoped setting in Visual Studio. We can do this by right-clicking on the ‘DataAccess’ project node in Solution Explorer and clicking on Properties. On the ‘Settings’ tab, we can add our connection string. I am going to side-step the problem that the connection string that is used in development may be different from that required on the deployment machine. For this blog, we will assume they are the same. This setting will be saved in XML format in the app.config file in the DataAccess project. By the way, the ‘Copy To Ouput Directory’ property for this file should be left in ‘Do not Copy’ state. Below is an example of the XML formatted app.config file.

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

<configuration>

<configSections>

</configSections>

<connectionStrings>

<clear />

<add name=MyConnStr connectionString=Data Source=.;Initial Catalog=library;Integrated Security=true; />

<add name=DataAccess.Properties.Settings.MyConnStr connectionString=Data Source=.;Initial Catalog=library;Integrated Security=true; />

</connectionStrings>

</configuration>

We can now create a reusable static class for encrypting our connection string. Below is the code for this class. The code is a bit tricky, because the config file we need to encrypt is not the app.config file that is located in our DataAccess project.  Neither is it the DataAccess.dll.config file in the /bin/debug directory of the ‘DataAccess’ project.   Instead it will be the EncryptConfig.EXE.config file in the /bin/debug or /bin/release directory of the ‘EncryptConfig’ project.

This static class ‘EncryptConnectString’ has only a single static method in it ‘ProtectConnectionString()’. This method will examine the EncryptConfig.EXE.config file and determine if it is encrypted. If it is encrypted, it returns otherwise it will encrypt the file. We use the ExecutablePath property of the static object System.Windows.Forms.Application to get the filepath to where the EncryptConfig.EXE.config file resides at runtime. The ‘ConfigurationManager’
class provides the ‘OpenExeConfiguration()’ method which takes a filepath string to retrieve the contents of the XML file and expose it through an instance of the ‘Configuration’ class. This class allows us to programmatically work with the configuration file without using one of the .NET XML classes like XmlDocument or XDocument.

Assuming the Configuration object was created successfully, we have to find the correct section of the config file and cast it as a ConnectionStringsSection object. The section name we need is ‘connectionStrings’ in this case. Next we need to verify that the section information we have is available for editing by examining the ‘IsLocked’ property of the ConnectionStringsSection object. Finally, we need to check if the section is encrypted by using the ‘IsProtected’ property.

If it is protected (encrypted), then we are done. If it isn’t encrypted, then we simply invoke the ‘ProtectSection()’ method of the SectionInformation object, pass it the ‘DataProtectionConfigurationProvider’ string as a parameter and all the magic of encrypting the connection strings (there may be several) is done for us by the .NET provided classes. Now that the config section has been encrypted, we need to save the changes. To do that we should set the ‘ForceSave’ property of the SectionInformation object to true and then invoke the ‘Save()’ method of the Configuration object.

Since the config file only needs to be encrypted once, we could put the ‘EncryptConnectString.ProtectConnectionString()’ method call in a some static constructor. In the code to the right, we placed the method call in the DataAccess constructor. We can now access the user setting like it was not encrypted at all. The .NET framework does all the work of decrypting the connection string for us behind the scenes.

If you examine the config file after it is encrypted, it should appear like what is shown below. The XML has been modified into another form with the connection string encrypted as a base64 string in the <CipherValue> tag. If you bring the config file into a code editor window, it will display errors on some of the tags. You can safely ignore those editor error messages.

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

<configuration>

<connectionStrings configProtectionProvider=DataProtectionConfigurationProvider>

<EncryptedData>

<CipherData>

<CipherValue>
AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAq09FHZA6nkuWLZ8pSjO7OAQAAAACAAAAAAAQZgAAAAEAACAA
AAAz3ZR+wIzLWdJNZUkoduMp3CPaUgaJvda2R9V/QtcmRQAAAAAOgAAAAAIAACAAAAD0jbN4Nb98FLzq5m
yiEt/VYnwCim5oPzdKqr7mvBwJYTAAAABwDXZrOKQtwUq7gKDoR4dnzK55IDANT7HWAuQZNnkhmPH8b+GC
VczCSUgdv9RNyctAAAAAya/c+Djo1v1B7gK7/FQWw9hull+EPs81JPdy6uJxkgcTUF0RfDBskq5g2si87k4US2Iz
/4E3+dK/yfWIyEpAcw==</CipherValue>

</CipherData>

</EncryptedData>

</connectionStrings>

</configuration>

If you compile and run this application a few times, you may receive the dreaded exception message listed below.

Failed to decrypt using provider
‘DataProtectionConfigurationProvider’.

Error message
from the provider: Key not valid for use in specified state.

(Exception from HRESULT: 0x8009000B)

Sometimes, the copied config files in the ‘EncryptConfig’ project get out of synch with the original config files in the DataAccess project.  You will notice that the DataAccess.dll.config file in the ‘DataAccess’ project was copied to the EncryptConfig.EXE.config file as well as to the EncryptConfig.vshost.exe.config file in the ‘EncryptConfig’ project (if you are using the debugger).   To fix this error, you can manually copy the unencrypted DataAccess.dll.config file in the DataAccess project to the EncryptConfig.EXE.config and EncryptConfig.vshost.exe.config files in the ‘EncryptConfig’ project.

The solution is now ready for deployment.  You will want to make sure that the config files are UNENCRYPTED for deployment (due to the machine key problem discussed at the top of this blog).