Today I’d like to tell you about some issues I had to solve in a project I had the last months, which is still ongoing. In the core it is a xbap (XAML browser application), which needs to use a wcf service.
The main challenge with xbap applications is the security context they run in. Most developers tend to enable “full trust”, when developing xbap applications and later wonder why they cannot deploy their applications without signing them with a real certificate.
In the case of using wcf with xbap and “partial trust” you will have to face some special issues. The main isssue is, that the domain name, where the xbap application is being downloaded from and the domain name of the server hosting the wcf service must be identical. This is, what many of the people (including me in the beginning) asking in the forums for a solution of using xbap with wcf do not know.
The second fact is, that you can only use basicHttpBinding in this scenario. Any other binding and the usage of wcf sessions wil fail. Remember java applets? Just the same problem…
In my case I had the following setup:
xbap application in “Internet” partial trust mode
wcf service in basicHttpBinding mode, no wcf sessions available
need for debugging the xbap and wcf service with vs 2008
need for some kind of wcf session replacement as I could not use wcf sessions
need for clustering/load balancing enviroment due to the massive amount of clients using the xbap
need for caching service on the server side which hosts the wcf service as big amounts of static data need to be available
As I first needed to have a session/cache replacement for wcf. I found a completely free and ready to use framework called “indeXus.Net Shared Cache”. This framework is not only a memory caching service, it is a multi-server replication cache, which can be used for almost anything that has to do with caches and sessions. Have a look at their homepage here and download the latest version. Compile it and install the windows caching service, which comes with the package. It is needed for my example to work.
Download the source code for my example here
So what about the wcf session/cache alternative I talked about? Well here is my proposal:
I created a serializable class, which will contain the cached data:
36 [Serializable]
37 public class CompositeType
38 {
39 bool boolValue = true;
40 string stringValue = “”;
41
42 public bool BoolValue
43 {
44 get { return boolValue; }
45 set { boolValue = value; }
46 }
47
48 public string StringValue
49 {
50 get { return stringValue; }
51 set { stringValue = value; }
52 }
53 }
This example class will be stored in the cache for each wcf session. Wait, wait, but there is no session! We will have to create a session by ourselves. Lets have a look at the little service interface I created for testing this:
11 [ServiceContract]
12 public interface IService1
13 {
14 [OperationContract]
15 Guid StartSession();
16
17 [OperationContract]
18 void SetValue(Guid pKey, string pValue);
19
20 [OperationContract]
21 string GetValue(Guid pKey);
22 }
And here we go with the implementation of our service interface:
13 public class Service1 : IService1
14 {
15 public Guid StartSession()
16 {
17 Guid result = Guid.NewGuid();
18 Cache.SharedCache.Add(result.ToString(), new CompositeType());
19 return result;
20 }
21
22 public void SetValue(Guid pKey, string pValue)
23 {
24 var obj = Cache.SharedCache.Get<CompositeType>(pKey.ToString());
25 obj.StringValue = pValue;
26 Cache.SharedCache.Add(pKey.ToString(), obj);
27 Debug.WriteLine(“SetValue:” +
28 Cache.SharedCache.Get<CompositeType>(pKey.ToString()).StringValue);
29 }
30
31 public string GetValue(Guid pKey)
32 {
33 Debug.WriteLine(“GetValue:” +
34 Cache.SharedCache.Get<CompositeType>(pKey.ToString()).StringValue);
35 return Cache.SharedCache.Get<CompositeType>(pKey.ToString()).StringValue;
36 }
37 }
There is a service function called “StartSession”, which creates a new cached object on the server side and returns a guid as the key to access this cached object in future calls.
The two additional functions “SetValue” and “GetValue” are simple testing methods to test accessing the cache and setting and getting the values.
The nature of the basicHttpBinding in WCF is, that the service object is created and destroyed with every function call. So you will not be able to use WCF sessions and per-session-instances. With my simple solution you will be able to have sessions as well and additionally have the possiblity to cluster and load balance your wcf server.
Now let’s get back to the xbap application, which is the reason, why we did all this hard work. Our xbap application wants to call some functions and wants to make sure, the server keeps its state until the wcf client object is destroyed. In our case, the only additional call we need to make after creating the service client is “StartSession”, which gives us back a uniqe session id, which can be used in the later function calls. Lets have a look at the example code inside of the xbap application now. My xbap application contains a listbox and a button. As soon, as we click the button, some service functions are called and we will get some outputs in our vs debug window as well:
30 private void button1_Click(object sender, RoutedEventArgs e)
31 {
32 Service1Client client = new Service1Client();
33 Guid sid = client.StartSession();
34 client.SetValue(sid, “123″);
35 listBox1.Items.Add(client.GetValue(sid));
36 client.SetValue(sid, “456″);
37 listBox1.Items.Add(client.GetValue(sid));
38 client.Close();
39 }
You can see, the first thing is to get a new client instance. After that, we create a session id and use it with every further function call. First I am putting a string value into the server’s cache. In the next line, I am getting the value back to put it into the listbox. This is done twice and then the eventhandler ends. What about destroying the cached objects? Well the caching server is self-responsible to do it after a configurable time. It will dispose all items, that are unused and not accessed for a long time and if the available memory gets low it will dispose the oldest items first.
Now we will take care of the fact, that debugging a xbap application, which uses a wcf service is some kind of tricky because of the “originating url” problem. What does this mean? When you start developing a xbap application, visual studio will start the compiled xbap file directly from the harddisk. As a result, the “originating url” will be the direct hard-disk path of the file and will shurely never be like the url of your webservice, which may be hosted on your local webserver or the development webserver in the taskbar. But the “Internet” security settings of the xbap application require the domainname, where the xbap is loaded from to be the same as the wcf services’. So the xbap must be started from a http url to achieve this.
To solve this problem, you have to know, that the originating url should be the fully qualified domain name of the computer, you are deploying or testing your application on. We want to develop on our local development workstation with vs 2008 and iis first and then deploy the xbap over the internet/intranet via a webserver in our company. First thing is to get the fqdn for your workstation. Have a look at your computer’s workplace properties:

My computer is a german one, but I believe you will know, which setting I mean. Look at the “Computername”. There you go: it is “pcdanielprivat.detonator.local”. In the beginning I struggled with this issue, as I used “localhost”, “127.0.0.1″ and “pcdanielprivat”, (which is NOT the fqdn, just the first part of it) for the url of the wcf service connection and for the xbap application debugging url. But as soon, as I used the fqdn for them, everything was working fine. Have a look at my post here in the msdn forum about this issue.
To make this scenario work, we cannot not use the WebDevWebserver for debugging our application, but the locally installed iis (which must be installed via “add/remove programs” in the control panel). Go to the project settings of your wcf web application project and get into the “Web” panel. By default “Use Visual Studio Delevopment Server” will be selected. Change this to “Use IS Web server” and then hit the “Create Virtual Directory” button.
After this step, create the wcf service reference in your xbap application as mentioned above. But what about debugging the xbap with vs? Well, there is the solution:
You will lose the ability to hit F5 directly after changing code of yur xbap application, this is the bad news. But you will instead be able to debug the xbap with wcf under “real” conditions with “Internet” security settings.
First, go to the properties of your xbap application and then open the “Publish” Tab. Make sure, you have the “Automatically increment revision with each publish” checkbox checked. Now change the “Publishing folder location” to your local iis instance (use the fqdn!) and add a folder to the root path. See my example screenshot, if you are unsure.

Then hit the “Publish Now” button. You will have to do this every time, you want to debug a new version of your xbap. This is the price for testing with “real” security settings.
Next, go to the properties of your xbap project and select the “Debug” Tab. VS will have selected “Start browser with URL” for you for default. This is one of the reasons, why using the wcf service from a partially trusted xbap will still not work. Change this setting to “Start External Program” and point it to the PresentationHost.exe as in the following screenshot.

You will have to set the “Command line arguments” to -debug -debugSecurityZoneURL “http://url_to_your_wcf_service_application_root” c:\projects\orwhereveryouhavetheproject\xbapapp\bin\Debug\xbapapp.xbap
Have a look here for the documentation of the PresentationHost.exe parameters.
The urls are just examples for your real urls, so you will have to replace them
Set the -debugSecurityZoneURL to the same URL, you entered as the publishing folder location in the previous step. This parameter tells the PresentationHost.exe to “fake” the originating url, when it loads the xbap from harddisk.
When hitting F5 in Visual Studio, you should now be able to debug your xbap application locally with wcf enabled. Yippieh!
I recommend to download my example application, which contains all the examples from this post and has all the settings applied, which worked for me. Just change them for your personal needs and feel free to modify the code.
Feel free to contact me, if you have any questions and additions.
References:
Debugging an XBAP / WCF application – Windows Vista + VS.NET 2008 « Niraj’s Weblog
indeXus.Net Shared Cache – distributed caching and replicated caching
MSDN Forums Home : Windows Presentation Foundation (WPF) : Using web services with xbap application