Friday, August 15, 2008

Embeding Silverlight control in web page OBJECT versus EMBED

When deploying a Silverlight control on a web page, there are several options available. You can either use the asp:Silverlight control or embed the control into your HTML using either the OBJECT or EMBED HTML tags.

One interesting gotcha that I ran into was when I tried to instantiate the Silverlight plug-in using the OBJECT tag in Firefox 3.0. The plug-in would just not load, which is strange, because before I updateded to Silverlight Beta 2 everything seemed to work fine. After poking around, I found that Apple's Safari web browser doesn't currently support the OBJECT element. Instead you have to use the EMBED tag, which works equally well in IE and Firefox. Perhaphs Microsoft is playing to the lowest common denomentor in an attempt to keep Silverlight 100% cross-browser compliant?

Either way, if you use the EMBED tag to instantiate the Silverlight plug-in, there are a couple of things to take note of:
  1. Custom parameters that are defined as individual
  2. Alternative content that displays when the Silverlight plug-in is missing will need to be wrapped in a NOEMBED element.
Here are 2 seperate implementations of a Silverlight control. One using OBJECT tag and the other using the more compliant EMBED tag.

OBJECT Implementation

<object type="application/x-silverlight" id="silverlightControl" width="390" height="100">
<param name="background" value="Yellow">
<param name="source" value="Chapter1.xaml">
<!-- Alternative content: -->
This content requires Silverlight.
<a href="http://www.microsoft.com/silverlight/downloads.aspx">
Get it Here.</a>
</object>

EMBED Implementation

<embed type="application/x-silverlight" id="silverlightControl" width="390" height="100" background="Yellow" source="Chapter1.xaml">
<noembed>
<!-- Alternative content: -->
This content requires Silverlight.
<a href="http://www.microsoft.com/silverlight/downloads.aspx">Get it here.</a>
</noembed>
</embed>

Labels:

Wednesday, August 6, 2008

Identifying the differences between CallContext Data Slots

Recently I was working on a server side caching strategy for permissions data. The key to the strategy was to place a user's permissions returned from a database call into the CallContext of WCF service. The code to do this looked something like this...

CallContext.SetData("permissionsKey", myPermissionsData);

All subsequent requests for permissions data would then be returned from the CallContext's cache permissions, thereby saving me from having to make redundant database calls for data that I already have.

myPermissionsData = (PermissionData)CallContext.LogicalGetData("permissionsKey")

Simple caching strategy...

During my testing I found that my cached data was not being returned. After further investigation I realized that I was setting the data using the CallContext's SetData method, but I was getting the data using the CallContext's LogicalGetData method. Come to find out, these are not the same. Seems there is a LogicalGetData method, LogicalSetData method, GetData method and SetData method on the CallContext object. So, it was a simple fix to use the LogicalSetData method in conjunction with the LogicalGetData method when implementing my caching strategy.

But why are there two methods that seemingly do the same thing? The documentation on MSDN doesn't really specify the differnce between the two.

Well... after doing some resarch and finding a post by Lucian Bargaoanu on the subject it seems that the difference has to do with AppDomains. Come to find out there is a LogicalCallContext and an IllogicalCallContext. LogicalCallContext will flow across appdomains. It will do this regardless of what type of object you have placed in context. The object doesn't have to implement ILogicalThreadAffinitive. When you call SetData with an ILogicalThreadAffinitive object, the data is set in the LogicalCallContext. When you call GetData it will first look in the LogicalCallContext and then in the IllogicalCallContext. You cannot have the same key in both CallContext(s).

In summary, objects stored using SetData will only flow across AppDomains if they implement ILogicalThreadAffinitive. Objects stored in LogicalSetData will flow across AppDomains even if they don't implement ILogicalThreadAffinitive. LogicalSetData handles seems to handle the ILogicalThreadAffinitive implementation for you.

Labels: , , , ,