How to use Proxy Classes.

To generate proxy classes for your project please see the documentation here.

Once the proxy classes have been generated, you may use them within your C# or VB.Net projects. Below are some code examples of how to use them.

Create a proxy class from an existing 'Entity' from the SDK
// Retrieve a standard entity object
var accountEntity = Service.Retrieve(
    "account", 
    new Guid("02215050-6890-453B-9B7A-7F54B54B81D0"), 
    new ColumnSet(true));

// Create a new proxy object with the current entity object
var accountProxy = new Account(AccountEntity);
// Access or set any of the properties on the proxy object
accountProxy.Address1_Street1 = "1234 Some Street";
accountProxy.Address1_City = "Some City";
Create a new proxy object and populate some of its properties
// Instantiate a new account and set some properties
var account = new Account();
account.Address1_Street1 = "1234 Some Street";
account.Address1_City = "Some City";
account.Address1_ZIP_PostalCode = "95663";
account.Address1_State_Province = "CA";
account.Address1_AddressType = Account.eAddress1_AddressType.BillTo;

// Create the account in CRM by using the 'Create' method on the proxy class
// The ID is automatically populated on the proxy object
account.Create(Service);

// You can also use the 'Save' method of the proxy class
account.Save(Service);

// Or alternately just use the 'Create' method of the IOrganizationService
// The proxy object is automatically converted to an 'Entity' object
// However, the ID of the entity is NOT automatically set in this instance
Service.Create(account);

// Update the street address
account.Address1_Street1 = "4321 Some Street";

// Since this is a smart object, when calling the 'Update' method
// only the address will be sent to CRM, not the entire object again.
account.Update(Service);

// You can also use the 'Save' method of the proxy class
account.Save(Service);

// Or alternately just use the 'Update' method of the IOrganizationService
// The proxy object is automatically converted to an 'Entity' object
Service.Update(account);
Differences between 'Create', 'Update' and 'Save' methods

Each proxy class has the following methods for saving information to CRM:

  • ProxyObject.Create() - Calls the 'Create' method of the IOrganizationService. The ID of the object is automatically populated upon successful creation.
  • ProxyObject.Update() - Calls the 'Update' method of the IOrganizationService. Only the properties that have changed are sent to CRM. See the 'Smart Tracking' feature below for more information.
  • ProxyObject.Save() - If the proxy object does not contain an ID then the 'Create' method will be called. If an ID exists then it is assumed that the object exists in CRM and the 'Update' method will be called.

  • IOrganizationService.Create() - Proxy objects are automatically converted to 'Entity' objects. However, the ID of the proxy object is not automatically set when using this method.
  • IOrganizationService.Update() - Proxy objects are automatically converted to 'Entity' objects. However, you lose the smart tracking feature when using the this method.
Smart Tracking - Only changes to the object are saved to CRM

In order to take advantage of the smart tracking feature of a proxy object, you must first load the object from CRM with any of the attributes that you might be changing. XrmToolkit then keeps track of which properties are changed and will only push those values to CRM as part of an 'Update' method call.

The smart tracking compares the before and after values of a property when determining whether a property has changed or not. So if you set a value on a property to the same value from when the object was originally loaded then the property will not be considered 'dirty' and will not push to CRM during a call to the 'Save' or 'Update' methods.

In order to use the smart tracking feature, you must use either the 'ProxyObject.Save()' or 'ProxyObject.Update()' methods. You cannot use the 'IOrganizationService.Update()' method directly.

// Retrieve the account object with all of its attributes
var accountProxy = Service.RetrieveProxy<Account>(new Guid("02215050-6890-453B-9B7A-7F54B54B81D0"));
// We know that this record has an 'Account Name' of 'Account A'
// Setting this property to the same name will NOT make this property 'Dirty'
accountProxy.AccountName = "Account A";
// Calling 'Save' or 'Update' on the record will not send any changes to CRM because nothing has changed
accountProxy.Save(Service); // Nothing happens
// Changing the 'Account Name' and 'Address Street 1'
accountProxy.AccountName = "Account A Updated";
accountProxy.Address1_Street1 = "1234 Main Street"; // Current Address is the same: 1234 Main Street
// Saving the proxy object only sends the 'Account Name' to CRM since it is the only property that has changed
accountProxy.Save(Service);
// Since the object has been saved, the smart tracking has been reset
// Setting the 'Account Name' to the same thing that was just updated will not send any changes to CRM
accountProxy.AccountName = "Account A Updated"; // Current Name is the same
accountProxy.Save(Service); // Nothing is sent to CRM since the record is not 'Dirty'
// Update the name to something different
accountProxy.AccountName = "Account A Updated Again";
// Revert the name back to the same value it was when it was last saved
accountProxy.AccountName = "Account A Updated";
// Saving the object will not send anything to CRM since it compares the current value to the last saved value
accountProxy.Save(Service); // Nothing is sent to CRM
Getting the text of an optionset value

There are 2 properties and 1 method that are generated for each optionset attribute:

  • Enum property to easily get or set the value
  • Property of type 'OptionSetValue' to easily set the value using an integer
  • Overloaded method to retrieve the current options text

When retrieving the text of an optionset, there are two options:

  • Retrieve the text using an IOrganiation service - This option will automatically retrieve the attribute metadata in the background to determine the text for the current value.
  • Retrieve the text using the attribute metadata - This option is more performant if you are calling the method several times. You can cache the metadata locally and then pass it to this method to get the text of the current value.
// Get the ownership type text by using the IOrganizationService overload
var ownershipTypeText = accountProxy.Ownership_Text(Service); // Attribute metadata is automatically retrieved to determine the text
   
// Get the ownership type text by using the attribute metadata overload
// First retrieve the attribute metadata
var attributeMetadata = Service.GetAttributeMetadata(Account.GetLogicalName(), Account.Properties.Ownership) as EnumAttributeMetadata;
var ownershipTypeText = accountProxy.Ownership_Text(attributeMetadata);
Enforce length, min, max on text and number attributes
// If the 'AcountName' exceeds the length allowed in CRM then throw the default error
Account.SetTextOptions(Account.Properties.AccountName, eTextOptions.ThrowError);
// If the 'Aging30' value falls outside the min or max in CRM, auto correct to either the min or max
Account.SetNumberOptions(Account.Properties.Aging30, eNumberOptions.CorrectMinAndMax);
Auto Truncate text attributes when text is longer than max length
// If the 'AcountName' exceeds the length allowed in CRM then truncate to the max allowed length
Account.SetTextOptions(Account.Properties.AccountName, eTextOptions.Truncate);