One of the biggest problems with using a WCF service in Silverlight is resolving the service itself in the correct place at all times. When moving code from your dev machine to staging and to production you may run in to issues. Using SSL and not using SSL can also be issues. So we came up with this simple solution to a complex problem.
Credit goes to
Jeff Wolfer on our team for creating this.
Here is how the solution is actually used. It uses generics:
private SLGlobalCustomer.SLGlobalCustomerClient client = SilverlightBaseLibrary.SLLocation.GetClient<SLGlobalCustomer.SLGlobalCustomerClient>("SLCustomer.svc");
client.SaveCustomersCompleted += new EventHandler<GlobalCustomerEdit.SLGlobalCustomer.SaveCustomersCompletedEventArgs>(client_SaveCustomersCompleted);
client.LoadCustomersCompleted += new EventHandler<GlobalCustomerEdit.SLGlobalCustomer.LoadCustomersCompletedEventArgs>(client_LoadCustomersCompleted);
client.LoadCustomersAsync(AutoLeadID);
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ServiceModel;
namespace SilverlightBaseLibrary
{
public static class SLLocation
{
public static Uri SilverlightLocation
{
get
{
return System.Windows.Application.Current.Host.Source;
}
}
public static Uri RootURL
{
get
{
return new Uri(SilverlightLocation, @"../");
}
}
public static Uri ServiceURL
{
get
{
return new Uri(RootURL, "Services/");
}
}
public static BasicHttpBinding WCFHttpBinding(long? MaxReceivedMessageSize)
{
BasicHttpBinding ret = new BasicHttpBinding();
//had to wrap this in a try catch because Expression Blend would throw a fit over this at design time if
//referencing GetClient in the constructor (not in a method basically)
try
{
if (System.Windows.Browser.HtmlPage.Document.DocumentUri.Scheme.ToLower() == "https")
{
ret.Security.Mode = BasicHttpSecurityMode.Transport;
}
else
{
ret.Security.Mode = BasicHttpSecurityMode.None;
}
ret.MaxReceivedMessageSize = MaxReceivedMessageSize ?? 65536;//65536 is default
}
catch { }
return ret;
}
private static System.ServiceModel.EndpointAddress GetEndpoint(string serviceName)
{
Uri uri = new Uri(SLLocation.ServiceURL + serviceName);
return new System.ServiceModel.EndpointAddress(uri.ToString());
}
public static T GetClient<T>(string serviceName) where T : class
{
return GetClient<T>(serviceName, null);
}
public static T GetClient<T>(string serviceName, long? MaxReceivedMessageSize) where T : class
{
object[] p = new object[] { WCFHttpBinding(MaxReceivedMessageSize), GetEndpoint(serviceName) };
return System.Activator.CreateInstance(typeof(T), p) as T;
}
}
}
Matt Watson
VinSolutions
Automotive CRM Software