CRM 2011 and Silverlight - SDK Samples

Hopefully this post will save you the many hours I spent messing around with the Silverlight SDK samples in the CRM 2011 SDK.

I was not able to get the Silverlight SDK samples to run. However after some simple changes I was able to get them to go. Here are the code changes I made to get it working.

If you run the "restsilverlightcontacteditor" sample as is [changing the service reference to your environment] you will end up with the following error:

To fix this cross-thread access error make the following changes in the MainPage.xaml.cs file:

Add a member for the contacts data collection:

 public partial class MainPage : UserControl
 {
 public MainViewModel TheMainViewModel { get; set; }
 private SynchronizationContext _syncContext;
 private ContosoContext _context;
 private String _serverUrl;
 private DataServiceCollection<Contact> _contacts;

 Next in the SearchContacts method replace the BeginExecute call with the following:

 private void SearchContacts(String criteria)
 {
 try
 {
 _contacts = new DataServiceCollection<Contact>();
 //Find all contacts
 if (String.IsNullOrEmpty(criteria))
 {
 DataServiceQuery<Contact> query = (DataServiceQuery<Contact>)_context.ContactSet;
 _contacts.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(OnContactSearchComplete);
 _contacts.LoadAsync(query);
 //query.BeginExecute(OnContactSearchComplete, query);
 }
 //Find contacts based on FullName containing text.
 else
 {
 DataServiceQuery<Contact> query = (DataServiceQuery<Contact>)_context.ContactSet.Where(c => c.FullName.Contains(criteria));
 //query.BeginExecute(OnContactSearchComplete, query);
 _contacts.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(OnContactSearchComplete);
 _contacts.LoadAsync(query);
 }

Next update the OnContactSearchComplete function as follows:

 //private void OnContactSearchComplete(IAsyncResult result)
 private void OnContactSearchComplete(object sender, LoadCompletedEventArgs e)
 {
 try
 {
 //Get the original query back from the result.
 //DataServiceQuery<Contact> query = result.AsyncState as DataServiceQuery<Contact>;
 
 //Update the ViewModel and notify the UI that Contacts collection has changed.
 //TheMainViewModel.Contacts = new DataServiceCollection<Contact>(query.EndExecute(result));
 TheMainViewModel.Contacts = _contacts;
 TheMainViewModel.NotifyPropertyChanged("Contacts");
 }
 catch (SystemException se)
 {
 _syncContext.Send(new SendOrPostCallback(showErrorDetails), se);
 }
 }

Next change the OnSaveContactsComplete method with the following:

  
 private void OnSaveContactsComplete(IAsyncResult result)
 {
 /*
 try
 {
 _context.EndSaveChanges(result);
 }
 catch (SystemException se)
 {
 _syncContext.Send(new SendOrPostCallback(showErrorDetails), se);
 }
 */
 Dispatcher.BeginInvoke(() =>
 {
 try
 {
 _context.EndSaveChanges(result);
 }
 catch (SystemException se)
 {
 _syncContext.Send(new SendOrPostCallback(showErrorDetails), se);
 }
 });
 }

Finally update the serverutility class so that you can run the project from visual studio with the following change:

  public static String GetServerUrl()
 {
 String serverUrl = String.Empty;
 
 //Try to get the ServerUrl from the Xrm.Page object
 serverUrl = GetServerUrlFromContext();
 if (string.IsNullOrEmpty(serverUrl))
 {
 serverUrl = "https://<your server name:port>/<your organization name>";
 }
 return serverUrl;
  }

Now the sample should actually work!

You can apply the similar changes to the "RESTEndpointPagingSilverlight" sample to get it to work too.