Writing XAML that gracefully degrades in partial trust scenarios

June 12, 2008

Developing WPF applications that run with full trust allows you to remain blissfully unaware of the problems involved with working in a partial trust environment. Once you begin to take the limitations of running in partial trust into account, life becomes more complicated (and more full of headaches). This blog post shows a utility class I made, called IfFullTrustExtension, which helps to create XAML files that work well in both trust environments.

Recently at work, I inherited an application that runs both as full trust and as partial trust. It runs under full trust when deployed as a desktop application, and partial trust when deployed as an XBAP. The Visual Designer I was working with made some excellent looking UI assets in Blend, but they were causing problems when running in the XBAP because they made use of bitmap effects. Bitmap effects have a history of not working in partial trust because they rely on unmanaged code and, thus, require UIPermissions to be instantiated. I really liked how those effects made the Designer’s UI assets look, but didn’t want to get into the messy business of applying those bitmap effects in code.

I needed a way to conditionally apply bitmap effects to elements in XAML. I slept on it, and when I woke up this morning, I had the following solution in mind…

The real problem here is that you cannot instantiate a bitmap effect class if you are running in partial trust. Since XAML has no inherent concept of “trust,” I needed to introduce it. I also needed to provide a way to conditionally instantiate objects declared in XAML, based on the level of trust given to the app by the CLR. This resulted in my new IfFullTrust markup extension, as seen below:

Using the markup extension in XAML looks like this:

Note that the DropShadowBitmapEffect XAML is in a CDATA block, and the default XML namespace is mapped to the standard WPF default namespace. Since the XAML is in a CDATA block, the bitmap effect will not be instantiated when the Page loads, but the XML it contains will remain intact so that my markup extension can read it.

If you run this XBAP project with full trust, it looks like this:

Notice that the drop shadow appears, as expected. The screenshot below shows how to make the XBAP run in partial trust, which is the default (and recommended) configuration for an XBAP:

If you run the app now, no exception is thrown and the app runs just fine. But, as seen below, there is no drop shadow:

[EDIT]

After posting this, I found that Andrew Smith had already blogged another, though different, use of markup extensions to work with bitmap effects.  His technique is described here.  My markup extension is not specific to working with bitmap effects, but his has the advantage of having the XAML be verified by the compiler.

[/EDIT]

Download the source code here. NOTE: Be sure to change the file extension from .DOC to .ZIP and then decompress it.

Advertisements

Three tips for working with XBAP

June 10, 2008

There is not much documentation out there that explains the best ways to work with Xaml Browser Applications (XBAPs). At my job, I recently inherited an application that is deployed both to the desktop and as XBAP, so I decided to study up on the topic. To my dismay, there is hardly anything out there beyond the basics. I intend on helping to fill that gap by blogging about XBAP-related tips and tricks that I learn along the way.

In this post, I share three tips that have helped me out a lot already.

XBAP Tip 1

When in doubt, clear it out. The XBAP applications are stored in a local cache on the client. Sometimes this is great, sometimes it can be a problem. If you make some changes in your code/XAML that you just know should be appearing when you run the app, but don’t, then it’s time to clean your cache. You can do so by running this:

rundll32 %windir%\system32\dfshim.dll CleanOnlineAppCache

I put that command in the Run dialog and just run it whenever I feel that the XBAP Gods are not smiling down upon me.

XBAP Tip 2

Unfortunately Snoop does not work with XBAPs. But…Mole does!! In order to molenate an XBAP you need to perform one extra step, that is not necessary for a normal WPF app. If you try to open the Mole debugger visualizer for an XBAP with the default security settings, you will receive this error from Visual Studio:

In case that image does not show up for you, it says: “The application you are debugging has insufficient privileges to allow the use of custom visualizers. Please see the documentation for the list of required privileges.”

In order to give an XBAP sufficient privileges to be molenated, you must open the project’s properties, go to the Security tab, and select the “This is a full trust application” option. This is seen below:

XBAP Tip 3

This tip is related to tip 2. Since you probably do not want to deploy your XBAP as a full trust application, you need to remember to revert the project setting back to “This is a partial trust application” at some point. If you want to be 100% certain that you’ve done so, simply call the following method from your main Page’s constructor (or wherever makes sense for you):

void VerifyPartialTrust()
{
  try
  {
    new DropShadowBitmapEffect();
    Trace.Fail("Warning: Project set to Full Trust!");
  }
  catch
  {
  }
}

Since a partial trust XBAP cannot touch bitmap effects, such as DropShadowBitmapEffect, creating an instance of one will throw an exception. If you can create an instance without an exception being thrown, the code above shows a warning message that you can’t miss!