Introduction
Here I am going to demonstrate solution for common problem which most of the developers face while developing Silverlight application with WCF Service. I have search lot of forums and could not found any good solution. So I am sharing my solution to make WCF service reference configurable. It makes easy for deploying on severs like Dev, QA, UAT etc. without code modification and republish.
Background
To implement this application, I am going to use the following technologies:
- Silverlight5 for the client tier
- WCF services -HTTP Binding
- WCF RIA Service V1.0 SP2
Creating Silverlight Business Application
Create new Silverlight business application. Name it to ‘BusinessAppMVVM’.
WCF Service
Add WCF service to the solution. Name it ‘BusinessAppMVVM.AppWCFService’.
Write one test method in ‘Service1.svc.cs’ .
public string GetUserAddress(string value)
{
return string.Format("You entered: {0}", value);
}
Add contract for this method.
[OperationContract]
string GetUserAddress(string value);
To enable a Silverlight control to access a service in another domain, the service must explicitly opt-in to allow cross-domain access. I am also going to deploy WCF service and Silverlight application on different servers.
Add ‘CrossDomainService’ service and add following code to it.
public class CrossDomainService : ICrossDomainService
{
Message ICrossDomainService.ProvidePolicyFile()
{
FileStream filestream = File.Open(@"ClientAccessPolicy.xml", FileMode.Open);
XmlReader reader = XmlReader.Create(filestream);
System.ServiceModel.Channels.Message result = Message.CreateMessage(MessageVersion.None, "", reader);
return result;
}
}
Create contract for this service.
[ServiceContract]
public interface ICrossDomainService
{
[OperationContract]
[WebGet(UriTemplate = "ClientAccessPolicy.xml")]
Message ProvidePolicyFile();
}
Add ‘ClientAccessPolicy.xml’ file for policy description.
="1.0" ="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>
Web Project
Add following ‘appsettings’ section to 'web.comfig’ file.
<appSettings>
-->
-->
-->
<add key="WCFServiceURL" value="<a href="http://localhost:59761/Service1.svc">http://localhost:59761/Service1.svc</a />" />
In this section you can have all the URL of servers where WCF service is being deployed like Dev, QA, UAT etc. Just uncomment URL which service you want to use in your Silverlight project without modifying any code. You don’t need to redeploy.
I am going to add RIA service to communicate this URL value to Silverlight project.
Add RIA service ‘BusinessAppRIAService’ in Web project.
Add following method in your new RIA service.
[Invoke]
public string GetWCFServiceAddress()
{
string url = ConfigurationManager.AppSettings.Get("WCFServiceURL");
return url;
}
Silverlight Client
Add service reference to Silverlight project.
Declare property in ‘app.xaml.cs’.
public string WCFServiceURL { get; set; }
Write following lines to call RIA service to get ‘WCFServiceURL’ value inside ‘Application_UserLoaded’.
var context = new BusinessAppMVVM.Web.Services.BusinessAppRIAContext();
context.GetWCFServiceAddress(GetWCFServiceURLCompleted, null);
Define ‘GetWCFServiceURLCompleted’ as follows.
private void GetWCFServiceURLCompleted(InvokeOperation<string> args)
{
try
{
WCFServiceURL = args.Value;
}
catch (Exception ex)
{
}
}
Now you are all set to write testing code to call WCF service. Add button control to ‘Home.xaml’. On button click event write following line of code.
private void button1_Click(object sender, System.Windows.RoutedEventArgs e)
{
BusinessAppServiceModel.Service1Client _serviceClient = null;
if (_serviceClient == null)
{
var myBinding = new BasicHttpBinding();
string url = ((App)Application.Current).WCFServiceURL;
if (url != null)
{
var address = new EndpointAddress(url);
_serviceClient = new BusinessAppServiceModel.Service1Client(myBinding, address);
}
else
{
MessageBox.Show("WCF Service URL is not found.");
}
}
_serviceClient.GetUserAddressCompleted -=
new EventHandler<GetUserAddressCompletedEventArgs>(OnGetUserAddressCompleted);
_serviceClient.GetUserAddressCompleted +=
new EventHandler<GetUserAddressCompletedEventArgs>(OnGetUserAddressCompleted);
_serviceClient.GetUserAddressAsync("Called from UI");
}
private void OnGetUserAddressCompleted(object sender, GetUserAddressCompletedEventArgs e)
{
MessageBox.Show(e.Result);
}
Deploy Silverlight and WCF service. Go to Web.config to change service url. You can see your project is working without redeploy.
At the End
You can download source code attached with this article. Hope this article will help you in deploying solution on different servers.
I would appreciate Vote for the Article and any comments or concerns or how things could be done better. Coming soon with my new findings.
Thanks for reading.