Deserialize XML into an Instance of BusinessEntity

banner art

[Applies to: Microsoft Dynamics CRM 4.0]

Find the latest SDK documentation: CRM 2015 SDK

You may have a scenario where an XML representation of a BusinessEntity class needs to be parsed into an in-memory object. One example is parsing the XML representation of DynamicEntity into an instance of this class within a plug-in assembly.

This sample is a stand-alone application that demonstrates how this can be done. Included here are two sample XML files that can be successfully parsed by this application. The sample parses any BusinessEntity XML string, and if the entity is of the type DynamicEntity, its properties are printed to the console. Child entities such as calendar rules on a calendar are handled as well.

Example

The following sample shows how to convert a DynamicEntity to a strongly typed BusinessEntity.

[C#]
namespace CrmClient
{
   using System;
   using System.IO;
   using System.Xml;
   using System.Xml.Serialization;
   using DynamicEntity.CrmServer;

   class App
   {
      public static void Main(string[] args)
      {
         App theApp = new App(args);

         theApp.Run();
      }

      public App(string[] args)
      {
         _args = args;
      }

      private void Run()
      {
         if (_args.Length < 1)
         {
            Console.WriteLine("Usage: DynamicEntityTest <input-file>");
            return;
         }

         string fileName = _args[0];
         Console.WriteLine("Reading XML from file {0}", fileName);

         // Use stream reader to display XML to be parsed.
         StreamReader sr = new StreamReader(fileName);
         string entityXml = sr.ReadToEnd();
         Console.WriteLine("XML to be parsed:");
         Console.WriteLine(new string('-', 60));
         Console.WriteLine("{0}", entityXml);
         Console.WriteLine(new string('-', 60));

         // Re-open the stream so that position is at the beginning of XML.
         sr = new StreamReader(fileName);

         // De-serialize the XML stream using the .NET XmlSerializer class.
         XmlRootAttribute root = new XmlRootAttribute("BusinessEntity");
         root.Namespace 
                    = "https://schemas.microsoft.com/crm/2006/WebServices";
         XmlSerializer xmlSerializer 
                    = new XmlSerializer(typeof(BusinessEntity), root);
         BusinessEntity entity 
                    = (BusinessEntity)xmlSerializer.Deserialize(sr);
         // End of deserialization.

         Console.WriteLine("Deserialized XML into object of type {0}",
                           entity.GetType().FullName);

         DynamicEntity dynamicEntity = entity as DynamicEntity;
         if (dynamicEntity != null)
         {
            DisplayDynamicEntity(dynamicEntity,
                         "de-serialized from XML string");
         }
      }

      /// <summary>
      /// Displays DynamicEntity instance and its properties.
      /// </summary>
      private void DisplayDynamicEntity(DynamicEntity entity,
                                        string message)
      {
         const string LineFormat = "  {0,-30}{1,-30}{2}";

         Console.WriteLine("DynamicEntity {0}: {1} with {2} properties:",
                       message, entity.Name, entity.Properties.Length);

         Console.WriteLine(LineFormat, "Property Name", "Property Type",
                           "Property Value");
         Console.WriteLine(LineFormat, "---", "---", "---");

         foreach (Property prop in entity.Properties)
         {
            Type propertyType = prop.GetType();

            // Format property value based on property type.
            string propertyValue = string.Empty;
            if (propertyType == typeof(StringProperty))
            {
               propertyValue = string.Format("'{0}'",
                                      ((StringProperty)prop).Value);
            }
            else if (propertyType == typeof(CrmDateTimeProperty))
            {
               CrmDateTime dt = ((CrmDateTimeProperty)prop).Value;
               propertyValue 
                      = string.Format("'{0}' date='{1}' time='{2}'",
                                      dt.Value, dt.date, dt.time);
            }
            else if (propertyType == typeof(KeyProperty))
            {
               Key key = ((KeyProperty)prop).Value;
               propertyValue = string.Format("'{0:D}'", key.Value);
            }
            else if (propertyType == typeof(LookupProperty))
            {
               Lookup lookup = ((LookupProperty)prop).Value;
               propertyValue 
                     = string.Format("'{0:D}' name='{1}' dsc='{2}'",
                                lookup.Value, lookup.name, lookup.dsc);
            }
            else if (propertyType == typeof(StateProperty))
            {
               string state = ((StateProperty)prop).Value;
               propertyValue = string.Format("'{0}'", state);
            }
            else if (propertyType == typeof(DynamicEntityArrayProperty))
            {
               DynamicEntity[] children 
                        = ((DynamicEntityArrayProperty)prop).Value;
               propertyValue 
                        = string.Format("number of child entities: {0}",
                                        children.Length);

               Console.WriteLine(LineFormat, prop.Name, propertyType.Name,
                                 propertyValue);

               Console.WriteLine(new string('>', 30));

               int nc = 1;
               foreach (DynamicEntity child in children)
               {
                  DisplayDynamicEntity(child,
                             message + " - child #" + nc.ToString());
                  nc++;
               }

               Console.WriteLine(new string('<', 30));

               continue;
            }
            else if (propertyType == typeof(OwnerProperty))
            {
               Owner owner = ((OwnerProperty)prop).Value;
               propertyValue 
                    = string.Format("'{0}' name='{1}' type='{2}'",
                              owner.Value, owner.name, owner.type);
            }
            else if (propertyType == typeof(CrmBooleanProperty))
            {
               CrmBoolean boolean = ((CrmBooleanProperty)prop).Value;
               propertyValue = string.Format("'{0}'", boolean.Value);
            }
            else if (propertyType == typeof(PicklistProperty))
            {
               Picklist picklist = ((PicklistProperty)prop).Value;
               propertyValue 
                    = string.Format("'{0}', name='{1}'", picklist.Value,
                                    picklist.name);
            }

            Console.WriteLine(LineFormat, prop.Name, propertyType.Name,
                           propertyValue);
         }
      }

      string[] _args;
   }
}

Sample XML File #1

<BusinessEntity xsi:type="DynamicEntity" Name="account" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://schemas.microsoft.com/crm/2006/WebServices">
  <Properties>
    <Property xsi:type="OwnerProperty" Name="ownerid">
      <Value type="systemuser">{1F8D8137-3BA0-450A-99E7-3DDB87B8F7E7}</Value> 
    </Property>
    <Property xsi:type="CrmBooleanProperty" Name="donotphone">
      <Value>0</Value> 
      </Property>
    <Property xsi:type="StringProperty" Name="address1_city">
      <Value>boston</Value> 
      </Property>
    <Property xsi:type="CrmBooleanProperty" Name="donotemail">
      <Value>0</Value> 
      </Property>
    <Property xsi:type="CrmBooleanProperty" Name="creditonhold">
      <Value>0</Value> 
      </Property>
    <Property xsi:type="StringProperty" Name="accountnumber">
      <Value>3344556677</Value> 
      </Property>
    <Property xsi:type="CrmBooleanProperty" Name="donotbulkemail">
      <Value>0</Value> 
      </Property>
    <Property xsi:type="CrmBooleanProperty" Name="donotfax">
      <Value>0</Value> 
      </Property>
    <Property xsi:type="StringProperty" Name="name">
      <Value>etertwe</Value> 
      </Property>
    <Property xsi:type="CrmBooleanProperty" Name="donotpostalmail">
      <Value>0</Value> 
      </Property>
    <Property xsi:type="CrmBooleanProperty" Name="donotsendmm">
      <Value>0</Value> 
      </Property>
    <Property xsi:type="PicklistProperty" Name="preferredcontactmethodcode">
      <Value>1</Value> 
      </Property>
  </Properties>
</BusinessEntity>

Sample XML File #2

Note that you must find the elements that contain GUIDs and replace the GUIDs with valid values from the system that the code is running in.

<BusinessEntity xsi:type="DynamicEntity" Name="calendar" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://schemas.microsoft.com/crm/2006/WebServices">
  <Properties>
    <Property xsi:type="LookupProperty" Name="organizationid">
      <Value name="alexant101" dsc="0">{EC43AE77   B3B2   4D4F   A7CA   0C5D5D900D19}</Value> 
    </Property>
    <Property xsi:type="CrmBooleanProperty" Name="isshared">
      <Value>0</Value> 
    </Property>
    <Property xsi:type="KeyProperty" Name="calendarid">
      <Value>{D46F9AB0   5EEA   D911   B72A   0007E9E17EFA}</Value> 
    </Property>
    <Property xsi:type="LookupProperty" Name="createdby">
      <Value name="Tkatch, Alexander" dsc="0">{0703484C   4DEA   4A10   8F5A   BD858655A432}</Value> 
    </Property>
    <Property xsi:type="CrmDateTimeProperty" Name="createdon">
      <Value date="07/01/2005" time="11:34 AM">2005   07   01T11:34:00   07:00</Value> 
    </Property>
    <Property xsi:type="CrmDateTimeProperty" Name="modifiedon">
      <Value date="07/01/2005" time="11:34 AM">2005   07   01T11:34:00   07:00</Value> 
    </Property>
    <Property xsi:type="LookupProperty" Name="modifiedby">
      <Value dsc="0" name="Tkatch, Alexander">{0703484C   4DEA   4A10   8F5A   BD858655A432}</Value> 
    </Property>
    <Property xsi:type="LookupProperty" Name="businessunitid">
      <Value dsc="0" name="alexant101">{9B8FF067   9EE9   D911   B72A   0007E9E17EFA}</Value> 
    </Property>
    <Property xsi:type="StringProperty" Name="name">
      <Value>Test Sdk Calendar</Value> 
    </Property>
    <Property xsi:type="DynamicEntityArrayProperty" Name="CalendarRules">
        <Value>
          <DynamicEntity Name="calendarrule">
          <Properties>
            <Property xsi:type="KeyProperty" Name="calendarruleid">
              <Value>{D56F9AB0   5EEA   D911   B72A   0007E9E17EFA}</Value> 
            </Property>
            <Property xsi:type="UniqueIdentifierProperty" Name="organizationid">
              <Value>{EC43AE77   B3B2   4D4F   A7CA   0C5D5D900D19}</Value> 
            </Property>
            <Property xsi:type="CrmDateTimeProperty" Name="starttime">
              <Value date="05/01/2005" time="12:00 PM">2005   05   01T12:00:00   07:00</Value> 
            </Property>
            <Property xsi:type="CrmBooleanProperty" Name="issimple">
              <Value name="No">0</Value> 
            </Property>
            <Property xsi:type="CrmNumberProperty" Name="extentcode">
              <Value formattedvalue="0">0</Value> 
            </Property>
            <Property xsi:type="CrmNumberProperty" Name="duration">
              <Value formattedvalue="480">480</Value> 
            </Property>
            <Property xsi:type="LookupProperty" Name="calendarid">
              <Value>{D46F9AB0   5EEA   D911   B72A   0007E9E17EFA}</Value> 
            </Property>
            <Property xsi:type="LookupProperty" Name="createdby">
              <Value dsc="0" name="Tkatch, Alexander">{0703484C   4DEA   4A10   8F5A   BD858655A432}</Value> 
            </Property>
            <Property xsi:type="CrmNumberProperty" Name="rank">
              <Value formattedvalue="0">0</Value> 
            </Property>
            <Property xsi:type="CrmDateTimeProperty" Name="createdon">
              <Value date="07/01/2005" time="11:34 AM">2005   07   01T11:34:00   07:00</Value> 
            </Property>
            <Property xsi:type="CrmDateTimeProperty" Name="modifiedon">
              <Value date="07/01/2005" time="11:34 AM">2005   07   01T11:34:00   07:00</Value> 
            </Property>
            <Property xsi:type="CrmNumberProperty" Name="timezonecode">
              <Value formattedvalue="4">4</Value> 
            </Property>
            <Property xsi:type="LookupProperty" Name="modifiedby">
              <Value dsc="0" name="Tkatch, Alexander">{0703484C   4DEA   4A10   8F5A   BD858655A432}</Value> 
            </Property>
            <Property xsi:type="CrmNumberProperty" Name="timecode">
              <Value formattedvalue="0">0</Value> 
            </Property>
            <Property xsi:type="StringProperty" Name="pattern">
              <Value>FREQ=DAILY;INTERVAL=1;</Value> 
            </Property>
            <Property xsi:type="UniqueIdentifierProperty" Name="businessunitid">
              <Value>{9B8FF067   9EE9   D911   B72A   0007E9E17EFA}</Value> 
            </Property>
            <Property xsi:type="StringProperty" Name="name">
              <Value>Test Sdk Calendar Rule</Value> 
            </Property>
            <Property xsi:type="CrmNumberProperty" Name="subcode">
              <Value formattedvalue="1">1</Value> 
            </Property>
          </Properties>
        </DynamicEntity>
      </Value>
    </Property>
  </Properties>
</BusinessEntity>

Example

The following sample shows how to convert an account represented as a dynamic entity to a strongly typed account business entity.

[Visual Basic .NET]

Sub ConvertDynamicEntitytoAccount()
    Dim service As New CrmService.CrmService
    service.Credentials = System.Net.CredentialCache.DefaultCredentials

    Dim accountDynamicEntity As New DynamicEntity
    'Set a few properties for test.
    Dim name As New StringProperty
    name.Name = "name"
    name.Value = "Fabrikam Inc."

    Dim accountnumber As New StringProperty
    accountnumber.Name = "accountnumber"
    accountnumber.Value = "AZ1200"

    Dim result As New Picklist
    result.Value = 2

    Dim shippingmethodcode As New PicklistProperty
    shippingmethodcode.Name = "address1_shippingmethodcode"
    shippingmethodcode.Value = result

    accountDynamicEntity.Name = EntityName.account.ToString()
    accountDynamicEntity.Properties 
               = New [Property]() {name, accountnumber,
                                   shippingmethodcode}

    ' Create a strongly typed class account to copy the dynamic entity into.
    Dim coreAccount As New account
    ' Call the method that converts the dynamic entity to a strongly typed
    ' business entity class. 
    coreAccount = ConvertDynamicEntityToCoreEntity(accountDynamicEntity)
    System.Console.Out.WriteLine(coreAccount.name + " " +
               coreAccount.accountnumber + " " +
               coreAccount.address1_shippingmethodcode.Value.ToString())
End Sub

' Convert a DynamicEntity to its equivalent strongly typed 
' business entity class.
Function ConvertDynamicEntityToCoreEntity(ByVal entity As DynamicEntity) As BusinessEntity
    Dim coreEntityName As String = entity.Name
    Dim entType As Type = Type.GetType("DynamicEntityVB.CrmService." & coreEntityName) 
    Dim init As ConstructorInfo = entType.GetConstructor(New Type() {})
    Dim ent As Object = init.Invoke(New Object() {})

    Dim p As [Property]
    For Each p In entity.Properties
        'For i = 0 To entity.Properties.Length - 1
        Dim entField As FieldInfo = entType.GetField(p.Name)
        If IsNothing(entField) Then
            System.Console.Out.WriteLine("Could not find attribute:" +
                                 p.Name + " on entity:" + coreEntityName)
        Else
            entField.SetValue(ent, GetAttribute(entity, p.Name))
        End If
    Next

    Return ent
End Function

'Return an object that represents the value of a dynamic entity. 
Function GetAttribute(ByVal entity As BusinessEntity, ByVal attribute As String) As Object

    If entity.GetType() Is GetType(DynamicEntity) Then

        Dim de As DynamicEntity
        de = CType(entity, DynamicEntity)
        Dim prop As [Property]
        For Each prop In de.Properties

            If prop.Name = attribute Then

                Dim field As FieldInfo = prop.GetType().GetField("Value")
                Return field.GetValue(prop)
            End If
        Next
        Return String.Empty

    Else

        Dim entField As FieldInfo = entity.GetType().GetField(attribute)
        Return entField.GetValue(entity)
    End If
End Function

See Also

Concepts

Reference

© 2010 Microsoft Corporation. All rights reserved.