Silverlight to WCF Cross Domain SecurityException

March 31, 2010 12:38

In debugging a fairly simple Silverlight control that calls into a WCF service I ran into an often encountered security exception having to do with cross-domain policy. Silverlight generally does not allow cross domain access unless that access is explicitly granted via a clientaccesspolicy.xml file. Given that I had to read through several sources (see References below) to formulate a solution to this problem, I decided to pull those sources of information together here for future reference.

The Problem

I originally ran into the following dialog when trying to debug my main solution which consists of a couple of nested WCF services and a Silverlight application hosted in a web app (the control makes a call to one of the services which in turn makes a call to the other service).

Here is the exception:

CommunicationException

And the text:

Communication exception was unhandled by user code

An error occurred while trying to make a request to URI 'http://localhost:7249/Service1.svc'. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. This error may also be caused by using internal types in the web service proxy without using the InternalsVisibleToAttribute attribute. Please see the inner exception for more details.

Examining the inner exception, I found:

{System.Security.SecurityException ---> System.Security.SecurityException: Security error.
   at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
   at System.Net.Browser.BrowserHttpWebRequest.<>c__DisplayClass5.<EndGetResponse>b__4
(Object sendState)
   at System.Net.Browser.AsyncHelper.<>c__DisplayClass2.<BeginOnUI>b__0(Object sendState)
   --- End of inner exception stack trace ---
   at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
   at System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
   at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.
HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)}

Given the somewhat complicated structure of the overall application, I decided to take a step back and create a very simple solution that contains a Silverlight app, its associated web hosting app, and a WCF service called “Service1”. I then added a service reference to “Service1” to the Silverlight app and ran the project. That got me back to the above CommunicationException. Good.

The Solution

There’s a lot of potential solutions to this problem (or so it seemed as I was working through it). What worked for me was adding a “clientaccesspolicy.xml” file to the root of the WCF service project. Here’s the contents of that file (and note that the name of the file is important as that is what Silverlight will look for by default):

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
    <cross-domain-access>
        <policy>
            <allow-from http-request-headers="*">
                <domain uri="*"/>
            </allow-from>
            <grant-to>
                <resource path="/" include-subpaths="true"/>
            </grant-to>
        </policy>
    </cross-domain-access>
</access-policy>

This grants access across the board with no restrictions.

When I re-run the application it works as expected.

But, wait, there’s more…

One other issue I had was with the VS Dev Web Server using a virtual path like:

http://localhost:7249/MyService/Service1.svc

This can happen if you have folders inside your solution, for example. The problem is that Silverlight is looking for clientaccesspolicy.xml in the root folder of the service but it now exists in \MyService. Fortunately, there’s an easy way to correct this.

Thanks to Tim Heuer for the solution which is to examine Properties on the WCF service project:

image

The solution then is to remove the folder designation so the virtual path contains the root slash only:

image

 

I re-ran again and everything works.

References

[ Follow me on Twitter ]


Animating the Fill Color of a Silverlight Ellipse

March 28, 2010 18:14

I'm working on this project where I intend to have a Silverlight control that auto-receives push notifications from a WCF service. The client end of the project involves displaying simple "pass" (green light) and "fail" (red light) indicators. Of course I want the indicators to change automatically as new information is received.

This then is a fairly basic tutorial on animating an ellipse to change from a "red" state to a "green" state and back. I'll use a timer to simulate receiving data from a WCF service, alternating the display state between "pass" (green) and "fail" (red). There is, of course, a smooth transition from one color to the other and back, and because of the 2 second timer interval and the 2 seconds it takes for the storyboard animation to complete, we wind up with a strobing ellipse that is constantly changing. This isn't necessarily the end-goal I had in mind, but it did have me captivated for a brief time.

Here is the "Fail" state:

image

And the "Pass" state:

image

The UI Element

For no particular reason I started with a button whose contents consist of a Ellipse and a TextBlock. The initial code for everything inside and including the Grid defined on line 4 came from Mark.NET's post Circular WPF Button Template. I contributed the button itself and the TextBlock, and I changed some of the colors. ;-)

   1: <Button BorderThickness="1" Width="400" Height="125">
   2:         <Button.Content>
   3:                 <StackPanel Orientation="Horizontal">
   4:                         <Grid Width="100" Height="100" Margin="5">
   5:                                 <Ellipse Name="buttonEllipse" Fill="Green">
   6:                                 </Ellipse>
   7:                                 <Ellipse>
   8:                                         <Ellipse.Fill>
   9:                                                 <RadialGradientBrush>
  10:                                                         <GradientStop Offset="0" Color="#00000000"/>
  11:                                                         <GradientStop Offset="0.88" Color="Black"/>
  12:                                                         <GradientStop Offset="1" Color="#80000000"/>
  13:                                                 </RadialGradientBrush>
  14:                                         </Ellipse.Fill>
  15:                                 </Ellipse>
  16:                                 <Ellipse Margin="10">
  17:                                         <Ellipse.Fill>
  18:                                                 <LinearGradientBrush>
  19:                                                         <GradientStop Offset="0" Color="#50FFFFFF"/>
  20:                                                         <GradientStop Offset="0.5" Color="#00FFFFFF"/>
  21:                                                         <GradientStop Offset="1" Color="#50FFFFFF"/>
  22:                                                 </LinearGradientBrush>
  23:                                         </Ellipse.Fill>
  24:                                 </Ellipse>
  25:                         </Grid>
  26:                         <TextBlock x:Name="testResultText" Text="Pass" FontSize="30" Margin="10" VerticalAlignment="Center" />
  27:                 </StackPanel>
  28:         </Button.Content>
  29: </Button>

The Storyboard

I wanted a smooth transition from one color to another when the (mock) test result state changes. I accomplished this by using two Storyboards: one for the green –> red transition, and another for the red –> green. Here's the XAML, which I defined inside the first Ellipse as an Ellipse.Resource:

   1: <Ellipse.Resources>
   2:     <Storyboard x:Name="colorStoryboardGreenToRed">
   3:         <ColorAnimationUsingKeyFrames BeginTime="00:00:00" 
   4:                 Storyboard.TargetName="buttonEllipse" 
   5:                 Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)">
   6:     
   7:             <!-- LinearColorKeyFrame creates a smooth, linear animation between values. -->
   8:             <LinearColorKeyFrame Value="Red" KeyTime="00:00:02" />
   9:     
  10:         </ColorAnimationUsingKeyFrames>
  11:     </Storyboard>
  12:     <Storyboard x:Name="colorStoryboardRedToGreen">
  13:         <ColorAnimationUsingKeyFrames BeginTime="00:00:00" 
  14:                 Storyboard.TargetName="buttonEllipse" 
  15:                 Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)">
  16:     
  17:             <!-- LinearColorKeyFrame creates a smooth, linear animation between values. -->
  18:             <LinearColorKeyFrame Value="Green" KeyTime="00:00:02" />
  19:     
  20:         </ColorAnimationUsingKeyFrames>
  21:     </Storyboard>
  22:     </Ellipse.Resources>

I defined a Storyboard, which is a container for other animation effects, that contains a single animation action: a ColorAnimationUsingKeyFrames, which at it's most basic is a way to transition a UI element's color from one to another. The two important attributes are "Storyboard.TargetName" and "Storyboard.TargetProperty". The former points to the previously defined Ellipse object as the target of this animation and the latter identifies the property we wish to transition. In this case it's Ellipse.Fill. LinearColorKeyFrame defines the smooth transition effect, changing our Ellipse from green to read and back again one frame at a time. Since KeyTime is set to 2 seconds, that's how long the transition will take.

If you want to read up on the basics of Silverlight animation then Animation Overview on MSDN is a great place to start.

Here's the full XAML:

   1: <UserControl x:Class="StrobingEllipse.MainPage"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   5:     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   6:     mc:Ignorable="d"
   7:     d:DesignHeight="125" d:DesignWidth="400">
   8:  
   9:     <StackPanel Orientation="Vertical">
  10:         <Button BorderThickness="1" Width="400" Height="125">
  11:             <Button.Content>
  12:                 <StackPanel Orientation="Horizontal">
  13:                     <Grid Width="100" Height="100" Margin="5">
  14:                         <Ellipse Name="buttonEllipse" Fill="Green">
  15:                             <Ellipse.Resources>
  16:                                 <Storyboard x:Name="colorStoryboardGreenToRed">
  17:                                     <ColorAnimationUsingKeyFrames BeginTime="00:00:00" 
  18:                                             Storyboard.TargetName="buttonEllipse" 
  19:                                             Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)">
  20:  
  21:                                         <!-- LinearColorKeyFrame creates a smooth, linear animation between values. -->
  22:                                         <LinearColorKeyFrame Value="Red" KeyTime="00:00:02" />
  23:  
  24:                                     </ColorAnimationUsingKeyFrames>
  25:                                 </Storyboard>
  26:                                 <Storyboard x:Name="colorStoryboardRedToGreen">
  27:                                     <ColorAnimationUsingKeyFrames BeginTime="00:00:00" 
  28:                                             Storyboard.TargetName="buttonEllipse" 
  29:                                             Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)">
  30:  
  31:                                         <!-- LinearColorKeyFrame creates a smooth, linear animation between values. -->
  32:                                         <LinearColorKeyFrame Value="Green" KeyTime="00:00:02" />
  33:  
  34:                                     </ColorAnimationUsingKeyFrames>
  35:                                 </Storyboard>
  36:                             </Ellipse.Resources>
  37:                         </Ellipse>
  38:                         <Ellipse>
  39:                             <Ellipse.Fill>
  40:                                 <RadialGradientBrush>
  41:                                     <GradientStop Offset="0" Color="#00000000"/>
  42:                                     <GradientStop Offset="0.88" Color="Black"/>
  43:                                     <GradientStop Offset="1" Color="#80000000"/>
  44:                                 </RadialGradientBrush>
  45:                             </Ellipse.Fill>
  46:                         </Ellipse>
  47:                         <Ellipse Margin="10">
  48:                             <Ellipse.Fill>
  49:                                 <LinearGradientBrush>
  50:                                     <GradientStop Offset="0" Color="#50FFFFFF"/>
  51:                                     <GradientStop Offset="0.5" Color="#00FFFFFF"/>
  52:                                     <GradientStop Offset="1" Color="#50FFFFFF"/>
  53:                                 </LinearGradientBrush>
  54:                             </Ellipse.Fill>
  55:                         </Ellipse>
  56:                     </Grid>
  57:                     <TextBlock x:Name="testResultText" Text="Pass" FontSize="30" Margin="10" VerticalAlignment="Center" />
  58:                 </StackPanel>
  59:             </Button.Content>
  60:         </Button>
  61:     </StackPanel>
  62: </UserControl>

The Codebehind

In the MainPage constructor I'll add a couple of events to capture the completion of each of the storyboards as well as kick off a timer which will initiate the Ellipse color change.

   1: public MainPage ()
   2: {
   3:     InitializeComponent ();
   4:  
   5:     // we'll change the test result text at the completion of each storyboard
   6:     colorStoryboardRedToGreen.Completed += colorStoryboardRedToGreen_Completed;
   7:     colorStoryboardGreenToRed.Completed += colorStoryboardGreenToRed_Completed;
   8:  
   9:     // simulate receiving results from WCF service
  10:     _receiveResults = new Timer (TimerReceiveResults, null, 2 * 1000, 0);
  11: }

The timer code is as follows:

   1: private void TimerReceiveResults (object state)
   2: {
   3:     // timer can stop for now
   4:     _receiveResults.Change (UInt32.MaxValue, UInt32.MaxValue);
   5:  
   6:     if (_whichStory)
   7:     {
   8:         Dispatcher.BeginInvoke (() => colorStoryboardGreenToRed.Begin ());
   9:     }
  10:     else
  11:     {
  12:         Dispatcher.BeginInvoke (() => colorStoryboardRedToGreen.Begin ());
  13:     }
  14:  
  15:     _whichStory = !_whichStory;
  16:  
  17:     // timer back to normal
  18:     _receiveResults.Change (2 * 1000, 0);
  19: }

I stop the timer while we're processing the event (always good practice), then check a flag to see if we have a "pass" or a "fail". Each Storyboard animation is started with the Begin method, and since I hooked up event handlers to the completion events I'll get a chance to do some more work when those are received.

Here's the code for those event handlers:

   1: void colorStoryboardRedToGreen_Completed (object sender, EventArgs e)
   2: {
   3:     testResultText.Text = "Pass";
   4: }
   5:  
   6: void colorStoryboardGreenToRed_Completed (object sender, EventArgs e)
   7: {
   8:     testResultText.Text = "Fail";
   9: }

Not much to it. I'm just updating the text of the button.

Conclusion

This is one of those things where the code is more a means to an end. In other words, a way to familiarize myself with a few new concepts which I can then take and actually do something useful with. Hope you also get something useful out of it.

Download: StrobingEllipse.zip

[ Follow me on Twitter ]


A Windows Phone 7 Silverlight TagList

March 20, 2010 17:28

I'm starting to learn the Windows Phone 7 platform. To start getting familiar with the process, I decided to write a TagList app that will access my TagCloud WCF service to retrieve the tags for this site. It will then display the tags in a list and allow the user to select each and automatically be brought to the corresponding web page.

If you need a list of the current installs for Windows Phone 7 check out my Getting Started with Windows Phone 7 Development. For assistance setting up an app, check out Pete Brown's Building your first Silverlight for Windows Phone Application or Scott Guthrie's Building a Windows Phone 7 Twitter Application using Silverlight.

Let's jump into it.

Adding a Service Reference to a Windows Phone 7 app

Once you've created a new Windows Phone 7 application, the next thing you'll need to do is add a service reference. You'll quickly find that you can't do this in the current RC version of Visual Studio 2010 because there's no "Add Service Reference…" menu item.

image

You can roll the proxy class yourself or use Visual Studio 2010 Express for Windows Phone, which comes with the Windows Phone Developer Tools CTP. The Express version has the missing menu item.image

You can leave the project open in Visual Studio 2010 while you open it in VS2010 Express for WP7. You could also just develop your application in the latter and forget about the former. Up to you.

In VS2010 Express for WP7 you add the service reference as usual. Here I'm using the WCF TagCloud service from which I retrieve tag information for the Silverlight TagCloud control on this site.

image

You can see that there is just the single web method, GetTags.

Back in VS2010 RC, you'll be asked to reload the project (assuming you left it open while editing externally) at which point you should now have the usual WCF service files.

image

 

The TagList UI

In MainPage.xaml I'll add a ListBox inside the default Grid along with an ItemTemplate to control data display.

   1: <ListBox Height="636" HorizontalAlignment="Left" Margin="10,10,0,0" Name="uxTagList" VerticalAlignment="Top" Width="460">
   2:     <ListBox.ItemTemplate>
   3:         <DataTemplate>
   4:             <TextBlock Text="{Binding TagName}" Margin="5"/>
   5:         </DataTemplate>
   6:     </ListBox.ItemTemplate>
   7: </ListBox>

In the codebehind, I'll add the code to setup and invoke the WCF service along with the async GetTagsCompleted method. Here's the entire class definition.

   1: public partial class MainPage : PhoneApplicationPage
   2: {
   3:     public MainPage ()
   4:     {
   5:         InitializeComponent ();
   6:  
   7:         SupportedOrientations = SupportedPageOrientation.Portrait | SupportedPageOrientation.Landscape;
   8:  
   9:         BlogTagService.TagCloudServiceClient blogTags = new TagCloudServiceClient ();
  10:         blogTags.GetTagsCompleted += new EventHandler<GetTagsCompletedEventArgs> (blogTags_GetTagsCompleted);
  11:         blogTags.GetTagsAsync (1, "http://www.itscodingtime.com/");
  12:     }
  13:  
  14:     void blogTags_GetTagsCompleted (object sender, GetTagsCompletedEventArgs e)
  15:     {
  16:         if (e.Error != null)
  17:             return;
  18:  
  19:         BlogTagService.CloudTag[] tags = e.Result;
  20:  
  21:         uxTagList.ItemsSource = from CloudTag cloudTag in tags
  22:                                 where cloudTag.TagName.Length > 0
  23:                                 select cloudTag;
  24:     }
  25: }

The first parameter for GetTagsAsync is the tag threshold, or the number of times the tag must have been used before being included in the query, and the second parameter is just so the returned CloudTag structure items contain the full url associated with the tag. Remember, in the context of a blog, each tag has its own url that a user can click on to get to the related content. (In retrospect I probably shouldn't even have that as a parameter as the service could just return relative urls)

In blogTags_GetTagsCompleted we use some LINQ to bind to the TagList control's ItemSource property.

Run the app and this is what you'll see:

image

Launching the Browser

So now we've got a list of the tags for this site. The next logical step is to allow the user to click (touch) each tag and see the corresponding content on this site. We'll accomplish this with an event handler to capture the MouseLeftButtonUp event and the Windows Phone WebBrowserTask class.

Adding the event handler yields this code for the ListBox:

   1: <ListBox Height="636" HorizontalAlignment="Left" Margin="10,10,0,0" Name="uxTagList" VerticalAlignment="Top" Width="460">
   2:     <ListBox.ItemTemplate>
   3:         <DataTemplate>
   4:             <TextBlock Text="{Binding TagName}" Margin="5" MouseLeftButtonUp="TextBlock_MouseLeftButtonUp" />
   5:         </DataTemplate>
   6:     </ListBox.ItemTemplate>
   7: </ListBox>

Before we code the event handler, we need to add a reference to Microsoft.Phone.Tasks and the corresponding namespace.

image

Then, we can make free use of the WebBrowserTask. Here is the MouseUp event handler:

   1: private void TextBlock_MouseLeftButtonUp (object sender, MouseButtonEventArgs e)
   2: {
   3:     var textBox = (TextBlock) sender;
   4:     var tagLink = string.Empty;
   5:  
   6:     foreach (var tag in _tags.Where (tag => tag.TagName == textBox.Text))
   7:     {
   8:         tagLink = tag.TagLink;
   9:     }
  10:  
  11:     if (!string.IsNullOrEmpty (tagLink))
  12:     {
  13:         var webBrowserTask = new WebBrowserTask {URL = tagLink};
  14:         webBrowserTask.Show();
  15:     }
  16: }

I moved the tag array gotten in the WCF service GetTagsCompleted event to class scope so that I can then query it here to get the tag link corresponding to the selected tag name. Then, I use the tag link to launch the browser.

Now, I had some problems with this. The browser would come up, but get stuck most of the time. The phone's "Back" button doesn't seem to do anything (I was expecting it to take me back to my app). This is CTP code, though, so you have to expect some quirks.

Finally, after playing with it for a while, I was able to get the web page to come up:

image

Too small to really do much with, so maybe I'll write an itscodingtime.com app next. ;-)

Conclusion

That's it for this demonstration. Hope you got some takeaways you can use in your own Windows Phone 7 projects.

Download: TagListApp.zip

 

[ Get 2GB of free online storage from Dropbox ]

[ Follow me on Twitter ]


Getting Started with Windows Phone 7 Development

March 19, 2010 07:52

Windows Phone 7 Here I've been investigating Android because it seemed like the most promising smartphone development platform when Microsoft goes and announces Windows Phone 7, which has the potential to change everything.

It's no secret that the Windows Mobile platform has languished for years, limping along in anemic fashion behind better, stronger contenders like the iPhone and any number of Android-based devices. From a Windows developer perspective and as someone who recognizes that smartphones are inexorably tied to our future as users and developers, I've wanted to dive into smartphone development for a while now. The iPhone somehow never appealed to me, though. Perhaps it's the almost foreign toolset. So I started looking at Android. At least you can write Android apps on Windows using tools and a language that are somewhat similar to Visual Studio and .NET.

Needless to say, my focus has shifted since the announcement of the Windows Phone 7 platform and CTP release of the development tools.

In this post I wanted to start with the very basics: what you need to download and install to get started writing Windows Phone apps. Given the CTP nature of things, and the fact that even Visual Studio as I write this is still in beta, there are quite a few pieces you need to assemble.

Windows Phone 7 apps are written in .NET using Visual Studio 2010 or Visual Studio 2010 Express for Windows Phone, Silverlight 4, and (optionally) Expression Blend. Given that Silverlight for Symbian is already in the works, we have a great opportunity here to leverage our existing Silverlight skills on not one but two mobile platforms. It just doesn't get any better than that.

As they stand now, here are the myriad downloads as they pertain to the tools you'll need.

Windows Phone

Windows Phone Developer Tools CTP

Includes:

  • Visual Studio 2010 Express for Windows Phone CTP
  • Windows Phone Emulator CTP
  • Silverlight for Windows Phone CTP
  • XNA 4.0 Game Studio CTP

Silverlight 4

1. Silverlight 4 Tools for Visual Studio 2010

The bare minimum for Silverlight or Silverlight for Windows Phone development.

Includes:

2. Silverlight 4 Toolkit

Not sure you need this for Windows Phone development per se, but if you're doing anything with Silverlight you'll want it anyway.

Expression Blend

I'm no Blend expert, but it's supposed to come in handy when developing Windows Phone apps.

Here are the downloads.

1. Expression Blend 4 Beta

2. Microsoft Expression Blend Add-in Preview for Windows Phone

3. Microsoft Expression Blend Software Development Kit (SDK) Preview for Windows Phone

Conclusion

Once everything is installed you're ready to go:

image

Rather than write up my own tutorial I will instead refer you to Pete Brown's Building your first Silverlight for Windows Phone Application, which does a nice job of walking you through creating your first project and adding some basic enhancements, and Scott Guthrie's Building a Windows Phone 7 Twitter Application using Silverlight, which is quite good as well (note that the url Scott provides to retrieve tweets is incorrect and should be "http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=").

There's still a lot to learn, but given that the toolset and choice of languages are familiar to most of us, we should have an easier time of it.

Resources

On the Web

Official Developer Guides

Books

Tutorials

On Twitter

[ Get 2GB of free online storage from Dropbox ]

[ Follow me on Twitter ]