XBAPs and Bitmap Effects

|

It has be a while since I last put together an XBAP (XAML Browser Application), so the myriad of security hurdles that one has to overcome has long since vanished from my short term memory; to the point where I am having to re-learning things. Bugger, I hate that! With that in mind, the purpose of this post is to document something I have rediscovered about XBAP’s and bitmap effects, in an attempt to help me remember and not have to keep relearning the same stuff.

So first off, bitmap effects are cool; they add a certain pizzazz to your UI, and if used subtly they really can make a big difference in the visual appeal of your UI:

image

However, you cannot use the BitmapEffect property on the UIElement class in an XBAP – note that UIElement is very high in the object hierarchy for WPF, so just about all visual elements contain this property by way of UIElement and then FrameworkElement; here is how you would use a BitmapEffect in XAML:

<Image Source="Images\Cube.png">
    <Image.BitmapEffect>
        <BevelBitmapEffect/>
    </Image.BitmapEffect>
</Image>

Attempting to run this XAML from within an XBAP, with the default configuration of Partial Trust, you see the following error message:

image

Interestingly, this is not a SecurityException, but simply a XamlParseException. However, if you are running in debug mode and happen to check the Output window, you see the following:

image

Note that the second to last line is a SecurityException, so the reason that the XAML cannot be parsed is due to a security failure. If you remove the BitmapEffect from the XAML, and only the BitmapEffect, all works as you would expect. From my experience this is the typical developer experience when falling over a partial trust issue, note that the SecurityException contains no additional information, let the needle in a haystack search begin; but more on that later.

It is also worth noting that WPF has matured, and is now able to leverage the GPU in your graphics card (or an approximation in software) by way of the Effect class. I am sure that there are some really awesome explanations as to how that works and what that is all really about, but that is not what this post is all about (if you know of a good explanation then please let leave a comment at the end of the post). From the point of view of a developer who has little interest in creating their own effects, to make use of this great feature simply use the new shiny Effect property, also found on the UIElement class, introduced in WPF 3.5 SP1.

However, WPF also does not allow an Effect class instance in Partial Trust – and therefore you still cannot use one in an XBAP without changing the permission requests. It is worth pointing out that not all the previous bitmap effects have been implemented as Effect‘s; at the time of writing there are only three:

  • BlurEffect
  • DropShadowEffect
  • ShaderEffect (used for creating custom effects)

Meaning that we cannot make use of the GPU today for the following type of effects:

  • Bevel
  • Emboss
  • OuterGlow

Personally, I do not think that this is any great loss, as the only effect that I miss is the OuterGlowBitmapEffect; it may well serve as a good catalyst to prompt me to learn a little more about creating my own effects.

To add an Effect to your application you use the following XAML:

<Image Source="Images\Cube.png" >
    <Image.Effect>
        <BlurEffect/>
    </Image.Effect>
</Image>

Attempting to run this XAML from within an XBAP, with the default configuration of Partial Trust, you see the following error message:

image

This time, while it is a XamlParseException, as before, but Microsoft have massively improved the exception handling with these effects as they actually tell me WHY it has failed: Request for the permission of type ‘System.Security.Permissions.UIPermission’ failed. Awesome, this means I can “tweak” my security settings to get the application to run when using an Effect:

image

Now this is the only permission I have to change, I do not have to make my whole application run in Full Trust to use the effects. I can take this a step further in for my application by configuring the properties of the specific permission, to prevent access to the Clipboard, if the application does not need it:

image

So thanks to the better error reporting when using the Effect’s classes in a partial trust environment, I can now successfully isolate just the permission I need, and make a calculated decision as to whether this is something the application really needs. Note however, tweaking this permission does not work when using the BitmapEffect classes, I still have not found that needle in the haystack yet.

image

So while I cannot show you the application running in the wild due to the “extra” permission required (click the image above to see the security error), the screenshot above does show the application running in my environment, where I’m happy to allow the application the permission it requires, which is perfect for an intranet or extranet environment. Alternatively, I could sign the application with an SSL certificate and you could trust that.

Finally, I want to talk quickly about the analyzer tool in Visual Studio 2008. The purpose of the tool is to work out if your application can run in partial trust; it is good at telling me if I need to run in full trust or not, which is very helpful, but it is really poor at telling me WHY! Making it really, really, really hard to fix these violations of partial trust, especially in these cases where I cannot easily remember all the details of what you can and cannot do, or if you are a newbie. As we have seen they have improved the exception handling for an Effect, however, I sincerely hope for more improvements with WPF 4.0 in this area. If anyone knows of any other tooling or a better way to keep on top of this issue, I would love to hear from you.

I hope this has been useful, as it was only a small “nice to have” feature that I added to one of my applications and it threw for me quite a while to isolate the problem and get the XBAP working at all, never mind the effects; but it was useful to also explore both BitmapEffect and Effect and work out the differences.

As usual if you have any comments, questions, flames, enhancements I would love to hear from you. In the meantime, think deeply and enjoy.

5 comments:

Stupid is as stupid does. said...

Think you for your great solution.

I read a blog and the writer had an another way to using BitmapEffect in XBAP by using Markup Extension.

Here is the url: http://blogs.infragistics.com/blogs/andrew_smith/archive/2008/04/09/bitmapeffects.aspx

Anonymous said...

"he only effect that I miss is the OuterGlowBitmapEffect; it may well serve as a good catalyst to prompt me to learn a little more about creating my own effects"

I will spare you some research. The reason we don't see any OuterGlowEffect available on the web is because this effect can't be created with the limited pixel shader support we're exposed. In fact even DropShadowEffect is a hack, they do some direct calls to the MIL layer to achieve it, you wouldn't be able to code this effect yourself.

In .NET 4, OuterGlowBitmapEffect has been removed and it's a total shame that we have NO replacement.

You can fake it with a DropShadow, but the result is *very* poor compare to what you could achieve with OuterGlow.

Paul said...

@Anonymous (is that your real name ;) Thanks for your comment and for reading.

-PJ

Anonymous said...

Hello all. Thanks for a great article. I developed an XBAP application and everything was wonderful until I tried to deploy it as a Partial Trust application. I spent a week trying to figure out why thing would not work. The lightbulb went on when I read your article. I removed the BlurEffect(s) from my XAML and was able to make progress. Thanks again for the article. You saved me another week of headaches!

Paul said...

You're welcome, I'm glad you got something useful from the post. Thanks for reading.

-PJ