Walkthrough: Use the SOAP Endpoint for Web Resources with Silverlight

[Applies to: Microsoft Dynamics CRM 2011]

This topic describes how to create a Microsoft Silverlight application using the SOAP endpoint for web resources. There are several specific manual steps you must follow to ensure you get expected results. This topic provides the procedures to create a properly configured Silverlight project and then includes some examples showing usage of the SOAP endpoint for web resources.

The files that represent the completed Microsoft Visual Studio 2010 Silverlight solution are located in the SDK download package at SDK\SampleCode\CS\Silverlight\SOAPforSilverlight.

A Microsoft Dynamics CRM 2011 managed solution representing the completed walkthrough is available at SDK\SampleCode\CS\Silverlight\SOAPforSilverlight\SOAPForSilverlight_1_0_0_1_managed.zip. You can confirm the functionality of this walkthrough by installing (importing) the managed solution. Because this is a managed solution, you can easily uninstall (delete) the solution after you have verified the behavior.

Prerequisites

This walkthrough expects the following:

  • You understand how to create Microsoft Dynamics CRM 2011 solutions and web resources.

  • You understand how to develop Silverlight applications.

Create the Silverlight Web Resources

These steps will create two web resources that include all the code required to use the SOAP endpoint for web resources.

  • Silverlight Web Resource: sample_/ClientBin/SoapForSilverlightSample.xap.

  • HTML Web Resource: sample_/SoapForSilverlightSample.html.

The procedures in this section will create web resources that represent a starting point for development. In the following Add Capabilities to Web Resources section, this walkthrough will update these web resources to add code to use the SOAP endpoint.

Create the Silverlight Project in Visual Studio 2010

  1. In Visual Studio 2010 create a Silverlight 4 application. This walkthrough will use the name SoapForSilverlightSample, but you can use whatever name you want. You will need to make changes as necessary because the name of the project is also the default namespace for the application.

  2. When prompted, accept the option to create a new website to host the Silverlight application. This walkthrough will use the name SoapForSilverlightSample.Web.

  3. In the SoapForSilverlightSample.Web project, delete the SoapForSilverlightSampleTestPage.aspx page and make the SoapForSilverlightSampleTestPage.html page the start page for the solution.

Creating the new website and removing the .aspx test page are recommended because in later steps we will make an HTML web resource using the HTML test page. The HTML web resource will provide the necessary context to test the Silverlight web resource without having to add the Silverlight web resource to an entity form.

Add a Service Reference to the Organization Service

  1. In the SoapForSilverlightSample project, right-click References and select Add Service Reference from the context menu.

  2. In the Add Service Reference dialog box, type the URL to the Organization service, and click Go.

    The URL to the service is located on the Developer Resources page of Microsoft Dynamics CRM 2011. In the Settings area, select Customizations, and then select Developer Resources.The URL has the following format:

    <organization URL>/XRMServices/2011/Organization.svc?wsdl
    
  3. Enter a namespace in the Namespace field, and then click OK.

    This walkthrough will use the namespace CrmSdk.

Add Supporting Classes and Edit Files

  1. In the SOAPforSilverlightSample project, add a new file with a class called SilverlightExtensionMethods.cs with the following code. The namespace for this class must match the namespace of your project.

    
    
    using System;
    using System.Windows.Browser;
    using System.ServiceModel;
    using System.Runtime.Serialization;
    using System.Collections.ObjectModel;
    using System.Collections.Generic;
    using System.ServiceModel.Description;
    
    namespace SoapForSilverlightSample.CrmSdk
    {
        partial class Entity
        {
            public Entity()
            {
                this.FormattedValuesField = new FormattedValueCollection();
                this.RelatedEntitiesField = new RelatedEntityCollection();
            }
    
            public T GetAttributeValue<T>(string attributeLogicalName)
            {
                if (null == this.Attributes) { this.Attributes = new AttributeCollection(); };
    
                object value;
                if (this.Attributes.TryGetValue(attributeLogicalName, out value))
                {
                    return (T)value;
                }
    
                return default(T);
            }
    
            public object this[string attributeName]
            {
                get
                {
                    if (null == this.Attributes) { this.Attributes = new AttributeCollection(); };
                    return this.Attributes.GetItem(attributeName);
                }
    
                set
                {
                    if (null == this.Attributes) { this.Attributes = new AttributeCollection(); };
                    this.Attributes.SetItem(attributeName, value);
                }
            }
        }
    
        [KnownType(typeof(AppointmentRequest))]
        [KnownType(typeof(AttributeMetadata))]
        [KnownType(typeof(ColumnSet))]
        [KnownType(typeof(DateTime))]
        [KnownType(typeof(Entity))]
        [KnownType(typeof(EntityCollection))]
        [KnownType(typeof(EntityFilters))]
        [KnownType(typeof(EntityMetadata))]
        [KnownType(typeof(EntityReference))]
        [KnownType(typeof(EntityReferenceCollection))]
        [KnownType(typeof(Label))]
        [KnownType(typeof(LookupAttributeMetadata))]
        [KnownType(typeof(ManyToManyRelationshipMetadata))]
        [KnownType(typeof(OneToManyRelationshipMetadata))]
        [KnownType(typeof(OptionSetMetadataBase))]
        [KnownType(typeof(OptionSetValue))]
        [KnownType(typeof(PagingInfo))]
        [KnownType(typeof(ParameterCollection))]
        [KnownType(typeof(PrincipalAccess))]
        [KnownType(typeof(PropagationOwnershipOptions))]
        [KnownType(typeof(QueryBase))]
        [KnownType(typeof(Relationship))]
        [KnownType(typeof(RelationshipMetadataBase))]
        [KnownType(typeof(RelationshipQueryCollection))]
        [KnownType(typeof(RibbonLocationFilters))]
        [KnownType(typeof(RollupType))]
        [KnownType(typeof(StringAttributeMetadata))]
        [KnownType(typeof(TargetFieldType))]
        partial class OrganizationRequest
        {
            public object this[string key]
            {
                get
                {
                    if (null == this.Parameters) { this.Parameters = new ParameterCollection(); };
    
                    return this.Parameters.GetItem(key);
                }
    
                set
                {
                    if (null == this.Parameters) { this.Parameters = new ParameterCollection(); };
    
                    this.Parameters.SetItem(key, value);
                }
            }
        }
    
        [KnownType(typeof(AccessRights))]
        [KnownType(typeof(AttributeMetadata))]
        [KnownType(typeof(AttributePrivilegeCollection))]
        [KnownType(typeof(AuditDetail))]
        [KnownType(typeof(AuditDetailCollection))]
        [KnownType(typeof(AuditPartitionDetailCollection))]
        [KnownType(typeof(DateTime))]
        [KnownType(typeof(Entity))]
        [KnownType(typeof(EntityCollection))]
        [KnownType(typeof(EntityMetadata))]
        [KnownType(typeof(EntityReferenceCollection))]
        [KnownType(typeof(Guid))]
        [KnownType(typeof(Label))]
        [KnownType(typeof(ManagedPropertyMetadata))]
        [KnownType(typeof(OptionSetMetadataBase))]
        [KnownType(typeof(OrganizationResources))]
        [KnownType(typeof(ParameterCollection))]
        [KnownType(typeof(QueryExpression))]
        [KnownType(typeof(RelationshipMetadataBase))]
        [KnownType(typeof(SearchResults))]
        [KnownType(typeof(ValidationResult))]
        partial class OrganizationResponse
        {
            public object this[string key]
            {
                get
                {
                    if (null == this.Results) { this.Results = new ParameterCollection(); };
    
                    return this.Results.GetItem(key);
                }
            }
        }
    
        public static class CollectionExtensions
        {
            public static TValue GetItem<TKey, TValue>(this IList<KeyValuePair<TKey, TValue>> collection, TKey key)
            {
                TValue value;
                if (TryGetValue(collection, key, out value))
                {
                    return value;
                }
    
                throw new System.Collections.Generic.KeyNotFoundException("Key = " + key);
            }
    
            public static void SetItem<TKey, TValue>(this IList<KeyValuePair<TKey, TValue>> collection, TKey key, TValue value)
            {
                int index;
                if (TryGetIndex<TKey, TValue>(collection, key, out index))
                {
                    collection.RemoveAt(index);
                }
    
                //If the value is an array, it needs to be converted into a List. This is due to how Silverlight serializes
                //Arrays and IList<T> objects (they are both serialized with the same namespace). Any collection objects will
                //already add the KnownType for IList<T>, which means that any parameters that are arrays cannot be added
                //as a KnownType (or it will throw an exception).
                Array array = value as Array;
                if (null != array)
                {
                    Type listType = typeof(List<>).GetGenericTypeDefinition().MakeGenericType(array.GetType().GetElementType());
                    object list = Activator.CreateInstance(listType, array);
                    try
                    {
                        value = (TValue)list;
                    }
                    catch (InvalidCastException)
                    {
                        //Don't do the conversion because the types are not compatible
                    }
                }
    
                collection.Add(new KeyValuePair<TKey, TValue>() { Key = key, Value = value });
            }
    
            public static bool ContainsKey<TKey, TValue>(this IList<KeyValuePair<TKey, TValue>> collection, TKey key)
            {
                int index;
                return TryGetIndex<TKey, TValue>(collection, key, out index);
            }
    
            public static bool TryGetValue<TKey, TValue>(this IList<KeyValuePair<TKey, TValue>> collection, TKey key, out TValue value)
            {
                int index;
                if (TryGetIndex<TKey, TValue>(collection, key, out index))
                {
                    value = collection[index].Value;
                    return true;
                }
    
                value = default(TValue);
                return false;
            }
    
            private static bool TryGetIndex<TKey, TValue>(IList<KeyValuePair<TKey, TValue>> collection, TKey key, out int index)
            {
                if (null == collection || null == key)
                {
                    index = -1;
                    return false;
                }
    
                index = -1;
                for (int i = 0; i < collection.Count; i++)
                {
                    if (key.Equals(collection[i].Key))
                    {
                        index = i;
                        return true;
                    }
                }
    
                return false;
            }
        }
    
        [KnownType(typeof(QueryBase))]
        [KnownType(typeof(Relationship))]
        [KnownType(typeof(EntityCollection))]
        [DataContract(Namespace = "http://schemas.datacontract.org/2004/07/System.Collections.Generic")]
        public sealed class KeyValuePair<TKey, TValue>
        {
            #region Properties
            [DataMember(Name = "key")]
            public TKey Key { get; set; }
    
            [DataMember(Name = "value")]
            public TValue Value { get; set; }
            #endregion
        }
    
        #region Collection Instantiation
        partial class EntityCollection
        {
            public EntityCollection()
            {
                this.EntitiesField = new ObservableCollection<Entity>();
            }
        }
    
        partial class Label
        {
            public Label()
            {
                this.LocalizedLabelsField = new LocalizedLabelCollection();
            }
        }
    
        partial class ColumnSet
        {
            public ColumnSet()
            {
                this.ColumnsField = new ObservableCollection<string>();
            }
        }
    
        partial class ConditionExpression
        {
            public ConditionExpression()
            {
                this.ValuesField = new ObservableCollection<object>();
            }
        }
    
        partial class FilterExpression
        {
            public FilterExpression()
            {
                this.ConditionsField = new ObservableCollection<ConditionExpression>();
                this.FiltersField = new ObservableCollection<FilterExpression>();
            }
        }
    
        partial class LinkEntity
        {
            public LinkEntity()
            {
                this.LinkEntitiesField = new ObservableCollection<LinkEntity>();
            }
        }
    
        partial class QueryByAttribute
        {
            public QueryByAttribute()
            {
                this.AttributesField = new ObservableCollection<string>();
                this.ValuesField = new ObservableCollection<object>();
                this.OrdersField = new ObservableCollection<OrderExpression>();
            }
        }
    
        partial class QueryExpression
        {
            public QueryExpression()
            {
                this.LinkEntitiesField = new ObservableCollection<LinkEntity>();
                this.OrdersField = new ObservableCollection<OrderExpression>();
            }
        }
    
        partial class OptionSetMetadata
        {
            public OptionSetMetadata()
            {
                this.OptionsField = new ObservableCollection<OptionMetadata>();
            }
        }
        #endregion
    }
    
  2. Edit the SOAPforSilverlightSample\Service References\CrmSdk\Reference.svcmap\Reference.cs file. Change each instance of “System.Collections.Generic.KeyValuePair<” to “KeyValuePair<”. This will change the reference from System.Collections.Generic.KeyValuePair to the class defined in the SilverlightExtensionMethods.cs file.

    You should find 22 instances.

    If you do not see the Reference.cs file, in Solution Explorer, click the Show All Files button.

  3. In the SOAPforSilverlightSample project, add a new class called SilverlightUtility with the following code:

    
    using System;
    using System.Collections.Generic;
    using System.Windows.Browser;
    using System.ServiceModel;
    using System.Text;
    using System.ServiceModel.Description;
    using SoapForSilverlightSample.CrmSdk;
    
    namespace SoapForSilverlightSample
    {
        internal static class SilverlightUtility
        {
            public static string ConvertToString(Exception exception)
            {
                string prefix = "";
    
                StringBuilder sb = new StringBuilder();
                while (null != exception)
                {
                    sb.Append(prefix);
                    sb.AppendLine(exception.Message);
                    sb.AppendLine(exception.StackTrace);
    
                    prefix = "Innner Exception: ";
                    exception = exception.InnerException;
                }
    
                return sb.ToString();
            }
    
            public static IOrganizationService GetSoapService()
            {
                Uri serviceUrl = CombineUrl(GetServerBaseUrl(), "/XRMServices/2011/Organization.svc/web");
    
    
                BasicHttpBinding binding = new BasicHttpBinding(Uri.UriSchemeHttps == serviceUrl.Scheme
                    ? BasicHttpSecurityMode.Transport : BasicHttpSecurityMode.TransportCredentialOnly);
                binding.MaxReceivedMessageSize = int.MaxValue;
                binding.MaxBufferSize = int.MaxValue;
                binding.SendTimeout = TimeSpan.FromMinutes(2);
    
                return new CrmSdk.OrganizationServiceClient(binding, new EndpointAddress(serviceUrl));
            }
    
            public static Uri GetServerBaseUrl()
            {
                string serverUrl = (string)GetContext().Invoke("getServerUrl");
                //Remove the trailing forwards slash returned by CRM Online
                //So that it is always consistent with CRM On Premises
                if (serverUrl.EndsWith("/"))
                    serverUrl = serverUrl.Substring(0, serverUrl.Length - 1);
    
                return new Uri(serverUrl);
            }
    
            /// <summary>
            /// Combines a URI with a relative URI
            /// </summary>
            /// <param name="baseValue">Base (absolute) URI</param>
            /// <param name="value">Relative URI that is to be used</param>
            /// <returns>Combined URI</returns>
            public static Uri CombineUrl(Uri baseValue, string value)
            {
                if (null == baseValue)
                {
                    throw new ArgumentNullException("baseValue");
                }
                else if (string.IsNullOrEmpty(value))
                {
                    return baseValue;
                }
    
                //Ensure that a double '/' is not being added
                string newValue = baseValue.AbsoluteUri;
                if (!newValue.EndsWith("/", StringComparison.Ordinal))
                {
                    //Check if there is a character at the beginning of value
                    if (!value.StartsWith("/", StringComparison.Ordinal))
                    {
                        newValue += "/";
                    }
                }
                else if (value.StartsWith("/", StringComparison.Ordinal))
                {
                    value = value.Substring(1);
                }
    
                //Create the combined URL
                return new Uri(newValue + value);
            }
    
            #region Private Methods
            private static ScriptObject GetContext()
            {
                ScriptObject xrmProperty = (ScriptObject)HtmlPage.Window.GetProperty("Xrm");
                if (null == xrmProperty)
                {
                    //It may be that the global context should be used
                    try
                    {
    
                        ScriptObject globalContext = (ScriptObject)HtmlPage.Window.Invoke("GetGlobalContext");
    
                        return globalContext;
                    }
                    catch (System.InvalidOperationException)
                    {
                        throw new InvalidOperationException("Property \"Xrm\" is null and the Global Context is not available.");
                    }
    
                }
    
                ScriptObject pageProperty = (ScriptObject)xrmProperty.GetProperty("Page");
                if (null == pageProperty)
                {
                    throw new InvalidOperationException("Property \"Xrm.Page\" is null");
                }
    
                ScriptObject contextProperty = (ScriptObject)pageProperty.GetProperty("context");
                if (null == contextProperty)
                {
                    throw new InvalidOperationException("Property \"Xrm.Page.context\" is null");
                }
    
                return contextProperty;
            }
            #endregion
    
    
        }
    }
    
  4. In the SOAPforSilverlightSample.Web project, open the SOAPforSilverlightSampleTestPage.html and edit the <head> element.

    • Replace this: <script type="text/javascript" src="Silverlight.js"></script>

    • With this: <script type="text/javascript" src="../ClientGlobalContext.js.aspx"></script>

    Note

    The relative path to the ClientGlobalContext.js.aspx page assumes that the SOAPforSilverlightSampleTestPage.html page will be used to create an HTML web resource with the name sample_/SOAPforSilverlightSampleTestPage.html. Because the forward slash character in the web resource name creates a simulated directory structure, you must use ../ before the file name to correctly associate the sample_/SOAPforSilverlightSampleTestPage.html to the WebResources/ClientGlobalContext.js.aspx page.

  5. Build your application.

Create Web Resources

  1. Create a new unmanaged solution in Microsoft Dynamics CRM 2011. For more information about creating solutions, see Create an Unmanaged Solution.

    This walkthrough will use the name “SOAPForSilverlight”, but you can use any name you want.

    Note

    This walkthrough will use a solution that is associated with a Solution Publisher that is configured to use the customization prefix “sample”. The Solution Publisher customization prefix is prepended to the name of any solution components created in the context of a solution. The customization prefix portion of the name of the web resources does not affect how these two web resources interact with each other because relative paths are used. The only important assumption is that these two web resources follow the same naming convention so that they appear within the same simulated folder structure. You can substitute any solution publisher customization prefix for both web resources without changing how they work.

  2. In the unmanaged solution, create two web resources by browsing and uploading the specified files from the Visual Studio project:

    Name

    sample_/SOAPforSilverlightSampleTestPage.html

    Type

    Web Page (HTML)

    Display Name

    SOAPforSilverlightSampleTestPage.html

    File

    SOAPforSilverlightSample.Web\SOAPforSilverlightSampleTestPage.html

    Name

    sample_/ClientBin/SOAPforSilverlightSample.xap

    Type

    Silverlight (XAP)

    Display Name

    SOAPforSilverlightSample.xap

    File

    SOAPforSilverlightSample.Web\ClientBin\SOAPforSilverlightSample.xap

  3. After you have created both web resources, verify that they can be opened by using the Preview button in the sample_/SOAPforSilverlightSampleTestPage.html web resource.

There is nothing to see when you preview the web resource because no capabilities have been added to the Silverlight web resource yet. The steps in this section provide a starting point for building your Silverlight web resource by using the SOAP endpoint. The procedures in the following section will verify that the preparatory steps were successful and provide some examples showing how to use OrganizationRequest/OrganizationResponse with late binding.

Add Capabilities to Web Resources

After you have created web resources using the procedures found in the preceding Create the Silverlight Web Resources section, you can begin to write code to add capabilities using the SOAP endpoint for web resources.

This walkthrough will add the following capabilities:

Add the User Interface

  1. Add the following XAML to the MainPage.xaml file in the SoapForSilverlightSample project.

    <UserControl x:Class="SoapForSilverlightSample.MainPage"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400">
    
        <Grid x:Name="LayoutRoot"
              Background="White">
            <Grid.RowDefinitions>
                <RowDefinition Height="227*" />
                <RowDefinition Height="73*" />
            </Grid.RowDefinitions>
            <TextBox HorizontalAlignment="Stretch"
                     Margin="5"
                     Name="ResultsBox"
                     VerticalAlignment="Stretch" />
            <Grid x:Name="ButtonGrid"
                  Grid.Row="1">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Button Content="List Accounts"
                        Grid.Column="0"
                        Height="23"
                        Margin="5"
                        Name="AccountList"
                        VerticalAlignment="Center"
                        Width="80"
                        Click="AccountList_Click" />
                <Button Content="List Entities"
                        Grid.Column="1"
                        Height="23"
                        Margin="5"
                        Name="EntityList"
                        VerticalAlignment="Center"
                        Width="75"
                        Click="EntityList_Click" />
            </Grid>
    
        </Grid>
    </UserControl>
    
  2. Edit the MainPage.xaml.cs file to include the following methods:

    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    
    namespace SoapForSilverlightSample
    {
        using SoapForSilverlightSample.CrmSdk;
        using System.Text;
    
        public partial class MainPage : UserControl
        {
            int MaxRecordsToReturn = 5;
    
            public MainPage(App app)
            {
                InitializeComponent();
                app.UnhandledException += new EventHandler<ApplicationUnhandledExceptionEventArgs>(app_UnhandledException);
            }
    
            private void ReportError(Exception ex)
            {
                this.ReportMessage("Exception: " + SilverlightUtility.ConvertToString(ex));
            }
    
            private void ReportMessage(string message)
            {
                this.Dispatcher.BeginInvoke(() => ResultsBox.Text = message);
            }
    
            private void app_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
            {
                this.ReportError(e.ExceptionObject);
            }
    
            private void AccountList_Click(object sender, RoutedEventArgs e)
            {
                try
                {
                    QueryExpression query = new QueryExpression()
                    {
                        EntityName = "account",
                        ColumnSet = new ColumnSet()
                        {
                            Columns = new System.Collections.ObjectModel.ObservableCollection<string>(new string[] { "name" })
    
                        },
                        Orders = new System.Collections.ObjectModel.ObservableCollection<OrderExpression>(new OrderExpression[]
                    {
                        new OrderExpression() { AttributeName = "name", OrderType = OrderType.Ascending }
                    })
                    };
    
                    query.PageInfo = new PagingInfo { Count = MaxRecordsToReturn, PageNumber = 1, PagingCookie = null };
    
                    OrganizationRequest request = new OrganizationRequest() { RequestName = "RetrieveMultiple" };
                    request["Query"] = query;
    
                    IOrganizationService service = SilverlightUtility.GetSoapService();
    
                    service.BeginExecute(request, new AsyncCallback(AccountList_ClickCallback), service);
                }
                catch (Exception ex)
                {
                    this.ReportError(ex);
                }
            }
    
            private void AccountList_ClickCallback(IAsyncResult result)
            {
                try
                {
                    OrganizationResponse response = ((IOrganizationService)result.AsyncState).EndExecute(result);
                    EntityCollection results = (EntityCollection)response["EntityCollection"];
    
                    StringBuilder sb = new StringBuilder();
                    if (results.Entities.Count == 0)
                    { sb.AppendLine("There are no Account records in the system."); }
    
                    foreach (Entity entity in results.Entities)
                    {
                        sb.AppendLine("Account Name = " + entity.GetAttributeValue<string>("name"));
                    }
                    if (results.MoreRecords)
                    {
                        sb.AppendLine("Only the first " + MaxRecordsToReturn + " records were returned.");
                    }
                    this.ReportMessage(sb.ToString());
    
                }
                catch (Exception ex)
                {
                    this.ReportError(ex);
                }
            }
    
            private void EntityList_Click(object sender, RoutedEventArgs e)
            {
                try
                {
                    OrganizationRequest request = new OrganizationRequest() { RequestName = "RetrieveAllEntities" };
                    request["EntityFilters"] = EntityFilters.Entity;
                    request["RetrieveAsIfPublished"] = false;
                    IOrganizationService service = SilverlightUtility.GetSoapService();
                    service.BeginExecute(request, new AsyncCallback(EntityList_ClickCallback), service);
                }
                catch (Exception ex)
                { this.ReportError(ex); }
    
    
            }
    
            private void EntityList_ClickCallback(IAsyncResult result)
            {
                try
                {
    
                    OrganizationResponse response = ((IOrganizationService)result.AsyncState).EndExecute(result);
                    System.Collections.ObjectModel.ObservableCollection<EntityMetadata> entities = (System.Collections.ObjectModel.ObservableCollection<EntityMetadata>)response["EntityMetadata"];
    
                    StringBuilder sb = new StringBuilder();
                    foreach (EntityMetadata entity in entities)
                    {
                        sb.AppendLine(entity.SchemaName);
                    }
                    this.ReportMessage(sb.ToString());
    
    
                }
                catch (Exception ex)
                {
                    this.ReportError(ex);
                }
    
    
            }
    
    
    
        }
    }
    
  3. In the App.xaml.cs file, locate the Application_Startup method and edit it by adding this to the parameters of the constructor for the MainPage.

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        this.RootVisual = new MainPage(this);
    }
    
  4. Build the solution.

    If you debug the solution at this point, the SoapForSilverlightSampleTestPage.html will load and display the List Accounts and List Entities buttons.

    If you click either button, the textbox will display the following message:

    Exception: Property "Xrm" is null and the Global Context is not available. 
       at SoapForSilverlightSample.SilverlightUtility.GetContext()
       at SoapForSilverlightSample.SilverlightUtility.GetServerBaseUrl()
       at SoapForSilverlightSample.SilverlightUtility.GetSoapService()
       at SoapForSilverlightSample.MainPage.AccountList_Click(Object sender, RoutedEventArgs e)
    

    This is expected because the web resource is not running in the context of the application.

  5. Update the sample_/ClientBin/SOAPforSilverlightSample.xap Silverlight web resource that you created in the first part of this walkthrough by uploading the most recent SoapForSilverlightSample.xap file from your Visual Studio project.

    Note

    You must publish the sample_/ClientBin/SOAPforSilverlightSample.xap web resource after you update it.

    After you update the Silverlight web resource you can view it by adding the Silverlight web resource to a CRM entity form or by using the Preview button while viewing the sample_/SOAPforSilverlightSampleTestPage.htmlHTML web resource.

This simple example shows how you can use the SOAP endpoint for web resources in a Silverlight web resource. For more information about writing code using the late bound programming paradigm, see Use the Late Bound Entity Class in Code

See Also

Tasks

Walkthrough: Use the SOAP Endpoint for Web Resources with JavaScript

Concepts

Use the SOAP Endpoint for Web Resources
Use the REST Endpoint for Web Resources
Use the Late Bound Entity Class in Code

Other Resources

Blog Post: User Impersonation with Silverlight

Microsoft Dynamics CRM 2011
Send comments about this topic to Microsoft.
© 2013 Microsoft Corporation. All rights reserved.