During our developments, we got some issues. Here, you’ll find tips to solve them. This is for people that are already familiar with both Silverlight and CRM.

1 - First Problem: authentication headers are not being set when using the Silverlight generated proxy. So the aim was to inject headers into the request ‘on the fly’.

There is an easy way to do it in SilverLight via custom chanels : OperationContextScope (System.ServiceModel).

To allow you to use CRM web service in SL, you have to add the class ‘MyCrmAuthenticationTokenSerializer’ in your code and call it to push crm authentication header in the request.

void Page_Loaded(object sender, RoutedEventArgs e)
{
CrmServiceSoapClient crmService = new CrmServiceSoapClient();
crmService.RetrieveCompleted += new EventHandler<CRMSilverlight.CrmSdk.RetrieveCompletedEventArgs>(crmService_RetrieveCompleted);
using (new OperationContextScope((IContextChannel)crmService.InnerChannel))
{
//here, we inject the CRM Authentication header
//The Xml formater is just to prevent some characters from being encoded (otherwise CRM can't parse the authentication token properly)

MessageHeader header = MessageHeader.CreateHeader("CrmAuthenticationToken", "http://schemas.microsoft.com/crm/2007/WebServices", "", new MyCrmAuthenticationTokenSerializer(0, "MyCrmOrganization", null));
// Insert SOAP header
OperationContext.Current.OutgoingMessageHeaders.Add(header);
crmService.RetrieveAsync("account", new Guid("1EB30C87-EA80-DD11-AE35-00155DA20A01"), cols);
}
}

//Result
void crmService_RetrieveCompleted(object sender, CRMSilverlightDirect.CrmSdk.RetrieveCompletedEventArgs e)
{
try{
TextBlock tb = new TextBlock();
account myAccount = (account)e.Result;
tb.Text = myAccount.name;
LayoutRoot.Children.Add(tb);

}
catch (Exception ex)
{
string wtf = ex.Message;
}
}

//You have to add this class to generate the CRM authentication header
public class MyCrmAuthenticationTokenSerializer : XmlObjectSerializer
{
int _authType;
string _organizationName;
string _callerId;

public MyCrmAuthenticationTokenSerializer(int authType, string organizationName, string callerId)
{
_authType = authType;
_organizationName = organizationName;
_callerId = callerId;
if (_callerId == null)_callerId = "00000000-0000-0000-0000-000000000000";
}

public override void WriteStartObject(XmlDictionaryWriter writer, Object graph)
{}

public override void WriteObjectContent(XmlDictionaryWriter writer, Object graph)
{
string authToken = string.Format("<AuthenticationType xmlns='http://schemas.microsoft.com/crm/2007/CoreTypes'>{0}</AuthenticationType><OrganizationName xmlns='http://schemas.microsoft.com/crm/2007/CoreTypes'>{1}</OrganizationName><CallerId xmlns='http://schemas.microsoft.com/crm/2007/CoreTypes'>{2}</CallerId>", _authType, _organizationName, _callerId);
writer.WriteRaw(authToken);
}

public override void WriteEndObject(XmlDictionaryWriter writer)
{}

public override bool IsStartObject(XmlDictionaryReader reader)
{
return true;
}
public override Object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
{return null; }
}

2 - Second Problem: Not all columns were returned when you use the strongly typed entity based classes in Silverlight.

The problem is that response comes back with non ordered attributes and that makes the SL proxy to null some values.  It’is important to notice that the CRM service doesn’t return values for null fields.

The solution: By using DynamicEntity you are by-passing the custom serialization so you should continue to work moving forward.

For your information: the strongly typed entity based classes are deprecated so using DynamicEntity is the correct approach to pursue.