Silverlight and WCF Deployment Gotcha
Silverlight has been around for over a year now and it’s a great technology. One gotcha that I ran into after deploying my web application was any calls from the Silverlight application to a local WCF service stopped working. I tested it locally before deploying and everything worked. I quickly realised that the endpoint address in the ServiceReferences.ClientConfig configuration file was pointing to my development server, not the production server. This file is compiled into the .xap file that is deployed to your web server, so instead of changing the endpoint address before you deploy, I’ll show you a simple trick that allows your application to work in development, test and production environments with a two lines of code. This is achieved by using the System.Uri class. By using this class you can tell your Silverlight application to point to a specific endpoint address instead of what’s defined in the ServiceReferences.ClientConfig file.
To begin with open Visual Studio 2008 and choose File > New > Project > Silverlight > Silverlight Application. Once that is done we need to create a Silverlight enabled WCF service. Right click the project and choose Add > New Item > Silverlight > Silverlight-enabled WCF service:
Name this service Person.svc. Once the file has been added to the project, add the following code:
C#
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Person
{
[OperationContract]
public string GetSurname()
{
return "Sheridan";
}
}
VB.NET
<ServiceContract(Namespace := ""), AspNetCompatibilityRequirements(RequirementsMode := AspNetCompatibilityRequirementsMode.Allowed)> _
Public Class Person
<OperationContract> _
Public Function GetSurname() As String
Return "Sheridan"
End Function
End Class
I have defined one public method called GetSurname which returns a string. I’m keeping this service as simple as possible for this example. Build your project before moving on.
Next open the Silverlight project. Add a reference to the WCF service we just created. Right click on the Silverlight project and choose Add Service Reference. The service reference dialog will appear. Click the Discover button and Visual Studio will automatically locate WCF services in the solution.
Now that we have the reference, we can turn our attention to the MainPage.xaml file. Add the following xaml:
<Grid x:Name="LayoutRoot">
<StackPanel Orientation="Horizontal">
<Button x:Name="btnGetSurname" Width="100" Height="25" Content="Go" Click="btnGetSurname_Click" />
<TextBox x:Name="txtSurname" Width="100" Height="25" />
</StackPanel>
</Grid>
Now it’s time to add code to the Button click event to call the service. Normally you would code the application like the following to call the WCF service:
C#
PersonRef.PersonClient client = new PersonRef.PersonClient();
client.GetSurnameCompleted += delegate(object s, PersonRef.GetSurnameCompletedEventArgs args)
{
txtSurname.Text = args.Result;
};
client.GetSurnameAsync();
VB.NET
Dim client As New PersonRef.PersonClient()
AddHandler client.GetSurnameCompleted, Function(s, args) AnonymousMethod1(s, args)
client.GetSurnameAsync()
Private Function AnonymousMethod1(ByVal s As Object, ByVal args As PersonRef.GetSurnameCompletedEventArgs) As Boolean
txtSurname.Text = args.Result
Return True
End Function
In the code above the code will call the WCF service and return the value. For this code to run, the application uses the ServiceReferences.ClientConfig configuration file and grabs the endpoint address value for the WCF service. On my machine the endpoint address is the following:
<client>
binding Configuration="CustomBinding_Person" contract="PersonRef.Person"
name="CustomBinding_Person" />
</client>
As you can see from code above, the application will connect to http://localhost:4192/Person.svc. If you run the project locally it works. But what happens when you deploy this to a separate web server? Your code will fail because the endpoint address is pointing to your local machine. One workaround that I found good is to use the System.Uri class in your code to point to a WCF service that is relative to the website. To make this work replace the code previously added with the following:
C#
Uri uri = new Uri(Application.Current.Host.Source, "../Person.svc");
PersonRef.PersonClient client = new PersonRef.PersonClient("CustomBinding_Person", uri.AbsoluteUri);
client.GetSurnameCompleted += delegate(object s, PersonRef.GetSurnameCompletedEventArgs args)
{
txtSurname.Text = args.Result;
};
client.GetSurnameAsync();
VB.NET
Dim uri As New Uri(Application.Current.Host.Source, "../Person.svc")
Dim client As New PersonRef.PersonClient("CustomBinding_Person", uri.AbsoluteUri)
AddHandler client.GetSurnameCompleted, Function(s, args) AnonymousMethod1(s, args)
client.GetSurnameAsync()
Private Function AnonymousMethod1(ByVal s As Object, ByVal args As PersonRef.GetSurnameCompletedEventArgs) As Boolean
txtSurname.Text = args.Result
Return True
End Function
In the code above I have created an Uri object which points to the Person WCF service in the web application. Since the code is being executed from the xap file, the URI is relative to the website. On the next line, the endpoint configuration name is used, CustomBinding_Person, and the remote address value is the uri.AbsoluteUri value.
C#
Uri uri = new Uri(Application.Current.Host.Source, "../Person.svc");
PersonRef.PersonClient client = new PersonRef.PersonClient("CustomBinding_Person", uri.AbsoluteUri);
VB.NET
Dim uri As New Uri(Application.Current.Host.Source, "../Person.svc")
Dim client As New PersonRef.PersonClient("CustomBinding_Person", uri.AbsoluteUri)
If you build this application, it can now be run locally or on a dedicated web server and the code will work without having to update the configuration file. Perfect!
The entire source code of this article can be downloaded over here
This article has been editorially reviewed by Suprotim Agarwal.
C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.
We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).
Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.
Click here to Explore the Table of Contents or Download Sample Chapters!
Was this article worth reading? Share it with fellow developers too. Thanks!
Malcolm Sheridan is a Microsoft awarded MVP in ASP.NET, a Telerik Insider and a regular presenter at conferences and user groups throughout Australia and New Zealand. Being an ASP.NET guy, his focus is on web technologies and has been for the past 10 years. He loves working with ASP.NET MVC these days and also loves getting his hands dirty with jQuery and JavaScript. He also writes technical articles on ASP.NET for SitePoint and other various websites. Follow him on twitter @
malcolmsheridan