The purpose of this tip is to outline all the steps needed to deploy a Silverlight application that leverages a WCF web service to a server. There are a number of issues you could run into if you forget a step. The errors you receive are often ambiguous and not very helpful; thus this blog.
Section #1: Creating a Silverlight-enabled WCF service.
If you are already familiar with how to create Silverlight enabled WCF services skip down to section #2.
Step #1. Using VS2010, create a new Silverlight application.
Step #2. In your Solution Explorer, right click on your web site and choose “Add New Item…”.
Step #3. Select the template for “Silverlight-enabled WCF service” and click the “Add” button once you give it a good name. By default, you will have one method called DoWork(). You can add more methods but for these methods to be visible to your Silverlight application they must include the [OperationContract] attribute above them.
Step #4. Build your web site project.
Step #5: In your Solution Explorer, right click on Silverlight application References node and choose “Add Service Reference”. Click the “Discover” button, change the namespace to be whatever you want (for the demo purpose I have called mine ServiceReferenceTest) and hit the “OK” button to continue.
Note: If you skipped #4 you would get the following error below. Make certain to build your web site first before you add or update a service reference.
Once added, make note of the address for your web service. It is pointing to localhost (http://localhost:2335/Service1TestWCF.svc) which is great for debugging locally but when it comes time to deploying your will want to change this to be the domain name of your server.
Step #6: Calls made to your web service are done asynchronously. You create a client object, specify the event that should be called when the web service is complete and then you call the method on the web service you want executed. For example, to call the DoWork() method I would execute the following code:
public MainPage()
{
InitializeComponent();
ServiceReferenceTest.Service1TestWCFClient client = new
ServiceReferenceTest.Service1TestWCFClient();
client.DoWorkCompleted += new
EventHandler<System.ComponentModel.AsyncCompletedEventArgs>
(client_DoWorkCompleted);
client.DoWorkAsync();
}
void client_DoWorkCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
}
Step #7: Let’s change DoWork() to return a string. In your web site open up your web service file (like Servivce1TestWCF.svc.cs) and change DoWork() to:
[OperationContract]
public string DoWork()
{
// Add your operation implementation here
return "Hello World";
}
Rebuild your web site. In your Silverlight application, right click on ServiceReferenceTest (or whatever you called it) and choose “Update Service Reference…”. This will download the latest schema for the web service. Go back to MainPage.xaml.cs and change your code to call and display string returned by DoWork().
public MainPage()
{
InitializeComponent();
ServiceReferenceTest.Service1TestWCFClient client = new
ServiceReferenceTest.Service1TestWCFClient();
client.DoWorkCompleted += new EventHandler<ServiceReferenceTest.DoWorkCompletedEventArgs>
(client_DoWorkCompleted);
client.DoWorkAsync();
}
void client_DoWorkCompleted(object sender, ServiceReferenceTest.DoWorkCompletedEventArgs e)
{
MessageBox.Show(e.Result);
}
You are now ready to try deploying this Silverlight application and it’s web service to a server.
Section #2: Deployment
In this scenario I have VS installed on the server and I have the Silverlight project files migrated to the server. Open the project and rebuild your entire application. Right click on your web site node in the Solution Explorer and choose “Publish…”. For Publish method choose “File System”. Set the Target location to be the place you want the web site to reside (such as c:\inetpub\wwwroot\WCFTest).
At this point your web site is published but not yet configured to run on your server. If you were to try to connect to your web site you might see the following error:
Parser Error Message: Unrecognized attribute ‘multipleSiteBindingsEnabled’. Note that attribute names are case-sensitive.
Attempt to remove this attribute and you might see:
Unrecognized attribute ‘targetFramework’. Note that attribute names are case-sensitive.
Line 8: <configuration>
Line 9: <system.web>
Line 10: <compilation debug="true" targetFramework="4.0" />
Line 11: </system.web>
Line 12:
If you see these errors make certain your server is configured to run in 4.0 and not 2.0. When you created your Silverlight project, due to a bug, even if you selected .NET 3.5 in the dropdown, a 4.0 application was still created. You can down target your application to 3.5 after it is created. Or, you can update your application pool to work with v4.0. To do this, open up IIS (Start->run->inetmgr). Click on the Application Pools node. Edit the application pool for this site changing it from v2.0 to v4.0.
Now, if you were to connect to your web site at this point, Silverlight would throw the following exception:
Webpage error details
User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET4.0C; .NET4.0E; .NET CLR 3.5.30729; .NET CLR 3.0.30729; InfoPath.2)
Timestamp: Mon, 3 May 2010 22:27:58 UTC
Message: Unhandled Error in Silverlight Application An exception occurred during the operation, making the result invalid. Check InnerException for exception details. at System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary()
at Tip11_WCF.ServiceReferenceTest.DoWorkCompletedEventArgs.get_Result()
at Tip11_WCF.MainPage.client_DoWorkCompleted(Object sender, DoWorkCompletedEventArgs e)
at Tip11_WCF.ServiceReferenceTest.Service1TestWCFClient.OnDoWorkCompleted(Object state)
Go back to your Silverlight project, right click on your Service Reference node and choose “Configure Service Reference”. Change the address to point from localhost (Example: http://localhost:2335/Service1TestWCF.svc) to the server (Example: http://www.yoursever.com/Service1TestWCF.svc).
Also, open up the file ServiceReferences.ClientConfig in your Silverlight project. Modify the endpoint address to also point to the server address instead of localhost.
<endpoint address=http://www.YourServer.com/Service1TestWCF.svc>
Finally, make certain your Silverlight site is configured in IIS to run as an application. I am no IIS expert, but I found one of these solutions does the trick:
Option #1: Right click on your web site node in IIS, select Convert To Application.
Option #2: In IIS, right click on the “Sites” node and choose “Add New Site”. Fill out the fields, hit OK and you should be good to go.
This will create an Application Pool for this site. Make certain that the newly created Application Pool has framework set to v4.0.
If anyone has other scenarios that can cause issues let me know and I will be happy to document them here.
Thanks,
–Mike







Hi,
well I think this wraps it up more or less but what if you don’t have VS on your server?
Sure you can unzip the xap and change the files yourself – what a pain.
I normaly put all the WCF service calls into a SL-library project and dynamically create the bindings in code (obviously the constructor will get the base url that you can easily get in Application_Startup (app.xml.cs) like
var baseUri = Host.Source.AbsoluteUri.Replace(Host.Source.AbsolutePath, “”);
The service-dll is a good point to wrap the event-based wcf-calls a bit too. I really like the continuation-passing style so I warp my calls to the wcf-methods with some Action parameters – works really nice (of course if you write the service-lib in F# async{…} just shines here
)
Best regards,
Carsten
If you do not have VS on your server I think you can just publish it on your developmenet box and then just copy the web site folder to your server. Have you tried that?
Always generates cross-domanin error, however the two ClientAccessPolicy.xml and crossdomain.xml files in c:\inetpub\wwwroot, any idea why. Thanks.