Issues When Updating Records Using the REST Endpoint for Web Resources and Silverlight

June 20, 2011

When you update records using Silverlight and the REST Endpoint for Web resources, unless you have worked around this issue you are updating every field even if the data hasn’t changed. This can lead to the following problems:

  • Potential for data loss
  • Auditing data does not correctly reflect actual changes
  • Event driven features such as Workflows (Processes) and Plug-ins execute when they are not needed

This post will describe the issue and provide a technique to avoid the problems.

Issue Description

The Microsoft Dynamics CRM SDK documents the following in the topic: Perform Basic Data Operations in Microsoft Dynamics CRM Using the REST Endpoint.

clip_image002

This behavior is a result of the way that a Silverlight application project generates proxies to work with an OData service. By default all properties defined for an entity are sent in an update request when you use the DataServiceContext.BeginSaveChanges Method. If you are working with an entity instance that was retrieved from a query it will contain all the current values and saving changes will update all the properties of the entity instance with those values even if they have not changed. If you instantiate a new entity instance and only update a few properties the update will overwrite other properties using the default null value for properties you haven’t set.

Technique to Avoid this Problem

To address this problem you need to provide some capability in your Silverlight application to track which properties have changed and only submit those properties when you save changes. Michael created the following solution that extends the Data Service Context to include change tracking for entity properties. I’ve found that it is relatively easy to apply this to an existing Silverlight application. Use the following steps to add and edit a new class file to your project:

Apply Data Service Context Extensions to A Silverlight Application Project:

1. Add a reference to System.Xml.Linq to your Silverlight application project if it doesn’t already exist

2. Create a new class file for your Silverlight application project. You might call it DataServiceContextExtensions.cs.

3. Paste the following code into the new file:

using System;
using System.Linq;
using System.Data.Services.Client;
using System.Reflection;
using System.Collections.Generic;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Xml.Linq;

namespace [[The Namespace of your Data Service Context]]
{
 partial class [[The name of your DataServiceContext Class]]
 {
  #region Methods
  partial void OnContextCreated()
  {
   this.ReadingEntity += this.OnReadingEntity;
   this.WritingEntity += this.OnWritingEntity;
  }
  #endregion

  #region Event Handlers
  private void OnReadingEntity(object sender, ReadingWritingEntityEventArgs e)
  {
   ODataEntity entity = e.Entity as ODataEntity;
   if (null == entity)
   {
    return;
   }

   entity.ClearChangedProperties();
  }

  private void OnWritingEntity(object sender, ReadingWritingEntityEventArgs e)
  {
   ODataEntity entity = e.Entity as ODataEntity;
   if (null == entity)
   {
    return;
   }

   entity.RemoveUnchangedProperties(e.Data);
  }
  #endregion
 }

 public abstract class ODataEntity
 {
  private readonly Collection<string> ChangedProperties = new Collection<string>();

  public ODataEntity()
  {
   EventInfo info = this.GetType().GetEvent("PropertyChanged");
   if (null != info)
   {

    PropertyChangedEventHandler method = new PropertyChangedEventHandler

              (this.OnEntityPropertyChanged);

    //Ensure that the method is not attached and reattach it
    info.RemoveEventHandler(this, method);
    info.AddEventHandler(this, method);
   }
  }

  #region Methods
  public void ClearChangedProperties()
  {
   this.ChangedProperties.Clear();
  }

  internal void RemoveUnchangedProperties(XElement element)
  {
   const string AtomNamespace = "http://www.w3.org/2005/Atom";
   const string DataServicesNamespace = "http://schemas.microsoft.com/ado/2007/08/dataservices";
   const string DataServicesMetadataNamespace = DataServicesNamespace + "/metadata";

   if (null == element)
   {
    throw new ArgumentNullException("element");
   }

   List<XElement> properties = (from c in element.Elements(XName.Get("content", AtomNamespace)
               ).Elements(XName.Get("properties", DataServicesMetadataNamespace)).Elements()
                                select c).ToList();

   foreach (XElement property in properties)
   {
    if (!this.ChangedProperties.Contains(property.Name.LocalName))
    {
     property.Remove();
    }
   }
  }


  private void OnEntityPropertyChanged(object sender, 

               System.ComponentModel.PropertyChangedEventArgs e)
  {
   if (!this.ChangedProperties.Contains(e.PropertyName))
   {
    this.ChangedProperties.Add(e.PropertyName);
   }
  }
  #endregion
 }
}

4. In the file you created replace the following placeholders with the correct references for your project:

image

5. Update the Reference.cs file

a. In Visual Studio 2010, click the icon with the tooltip Show All Files at the top of the Solution Explorer window.

b. In Solution Explorer, expand the service reference you created and the Reference.datasvcmap file to view the Reference.cs file.

c. Use Find/Replace to change:

: global::System.ComponentModel.INotifyPropertyChanged

to

: ODataEntity, global::System.ComponentModel.INotifyPropertyChanged

Note: There should be one instance for each entity.

6. Recompile your project, update your Silverlight Web resource with the new .xap file and test it.

SDK Update

In next release of the SDK (version 5.05) the SDK topic Use the REST Endpoint with Silverlight Web Resources will contain steps include this method. Each of the Silverlight samples that update records will also be updated to include these extensions.

Cheers,

Jim Daly, Michael Scott

Read the full article →

HOWTO: Use a custom query in a dashlet

June 17, 2011

Editor’s Note: This tip comes from a forums post by our very prolific community member, Jason Eggers ( probably better known by his forums, Twitter, and IRC handle ‘eggsurplus’ ). He’s contributed several bug fixes and features to SugarCRM over the years, including the dashlet auto-refresh feature in the recently released Sugar 6.2. He’s also [...]

Read the full article →

Meet the Salesforce.com MVPs

June 16, 2011

Posted By: Ruthie Miller

Read the full article →

Quick Entry Module

June 16, 2011

Making the complex seem easy.
Epicom created a Quick Entry Module for its customer, The Texas Tribune, to speed-up data entry for donations and advertisement purchases. Epicom’s Quick Entry Module leverages SugarCRM’s architecture and relates data between modules. For example, a Contact can be related to an Account and a Quote can be related to both.
Creating [...]

Read the full article →

Power User Tip: End Series for Recurring Appointments

June 15, 2011

Microsoft Dynamics CRM 2011 introduces the capability to create recurring appointment in CRM and its bi-directional synchronization support with Outlook. In this blog I am going to discuss about one of the enhanced capabilities introduced by CRM which …

Read the full article →

Want to win an iPad 2? Then be a part of the SugarCRM bug fix contest!

June 15, 2011

For those of you who have those annoying bugs in SugarCRM that they’d love to have fixed once and for all, now’s your chance. We are holding a bug fix contest starting next week, and the person submitting the most number of bug fixes during that period will walk away with a brand new Apple [...]

Read the full article →

Custom Support Portal

June 14, 2011

The purpose of email chains and Google docs is to streamline the collaboration process and keep one centralized communication channel among groups.  If your company is using a Customer Relationship Management (CRM) system, customer portals take on the collaboration role and are far more efficient in organizing information. Portals allow customers to interact with the [...]

Read the full article →

Oracle CRM Industry-Specific Innovations

June 14, 2011

Oracle VP Aaron Shidler on Oracle’s Top 5 CRM Industry-Specific Innovations As vice president of Oracle Fusion Application strategy, industry veteran Aaron Shidler has a unique view into the breadth and depth of Oracle Applications. We asked hi…

Read the full article →

Microsoft Dynamics CRM Online Demonstration Kit

June 14, 2011

The Microsoft Dynamics CRM Product Management team is happy to announce the availability of the Microsoft Dynamics CRM Online Demonstration Kit.  This Kit was optimized to facilitate a stand-alone Microsoft Dynamics CRM Online environment.

Scenarios
Included in this Kit is more comprehensive data, Dashboards, Workflows and Dialogs illustrating core CRM capabilities in expanded scenarios.  Read on below to find detailed instructions on how to download and setup these assets.

What’s covered in this kit:

  • Extensive Sample Data
  • 13 Dashboards
  • 17 Workflows
  • 2 Dialogs
  • 1 Web Resource (phone number auto-formatting jscript)
  • 1 Option Set (Timeframe drop-down list to use across entities)
  • 2 E-mail Templates

CRM Online Scenarios

Cheers,

Eric Boocock, Senior Technical Product Manager

 

The following files are included in the Kit and can be downloaded here:

  • CRM Solution (managed, unmanaged)
  • Sample Data
  • Demonstration Script
  • Demonstration Kit Overview

* For more details on managed vs. unmanaged solutions click here.
* Download the Sample Data and unzip the folder before starting the setup process.

Note: This data is based on US Dollar currency. If your currency is not US Dollar you must add the USD currency with the proper conversion rate to your base currency before proceeding.

image

Setup Process

Note: If you encounter any errors during the data import process address them before continuing to import additional entities as future dependencies may be compromised.

  1. Import the basic CRM Administrative data (Users, Sites, Queues, Subjects, Products, etc.) accepting all the Import Wizard default settings.
    • Workplace > Imports, click imagein the Ribbon
      • Import 1-Admin, once successful proceed,
      • Import 2-Admin, once successful proceed,
      • Import 3-Admin, once successful proceed,
  2. Import the CRM Solution
    • Settings > Solutions, click imagein the toolbar
      • Select Solution Package: Browse to the Solution CRM2011Scenarios_1_0_0_0, click Next,
      • Solution Information: click Next,
      • Import Options: Do NOT check the box to activate processes, click Next,
        (The data is properly formatted and if you activate the processes workflows will alter the data.) 
      • Importing Solution: click Publish All Customizations, click Close.
  3. Enable All Users
    • Settings > Administration > Users, change view to Disabled Users, Multi-select all Users and click image in the ribbon.
    • Confirm Users Activation: click OK
  4. Activate the following Sales Processes
    image
    • Settings > Processes, multi-select the processes and click image in the toolbar.
  5. Import Sales, Marketing & Service data (repeating step # 1 above)
    • Import 4-Marketing, once successful proceed,
    • Import 5-Sales, once successful proceed,
    • Import 6-Sales, once successful proceed,
    • Import 7-Service, once successful proceed,
  6. Import custom Data Map for Activities
    • Settings > Data Management > Data Maps, click image in the toolbar
    • Browse and select Activities_customized_PhoneCall (in Sample Data folder), click OK
  7. Import final data set – Activities (repeating step # 1 above except selecting the imported custom data map from previous step)
    • Upload Data File: Browse to and select Import 8-Activities, click Next
    • Review File Upload Summary: click Next
    • Select Data Map: Select the Customized Data Map Activities_customized_PhoneCall, click Next
      image
    • Accept remaining Import Wizard defaults to complete the import.
  8. Recalculate Goals
    • Sales > Goals, select Central Region Revenue and click image in the Ribbon. This will recalculate all the Goals.
  9. Activate all Processes
    • Settings > Processes, multi-select all workflows and click image in the toolbar
  10. Change Product Default Price Lists to Retail
    • Settings > Product Catalog > Products
      • Open Kit of Product A & B, Set Default Price List = Retail, click Save & Close
      • Open Product A (SKU JJ202), Set Default Price List = Retail, click Save & Close
      • Open Product B (SKU AX305), Set Default Price List = Retail, click Save & Close
  11. Run workflow to set Account Products Owned
      • Sales > Opportunities > Won Opportunities, multi-select all records, click  in the Ribbon, select Set Account Relationship Type…, click OK
  12. OPTIONAL:There are 10 Users included within the Sample Data. To login as one of these Users you must assign them a valid Windows Live ID and accept the invitation
    • Settings > Administration > Users, open User record
      • Click image in the Ribbon
      • Enter the new Windows Live ID, click Submit
      • Send new Invitation

Read the full article →

Network like a rockstar: 7 ways to get social at Dreamforce

June 14, 2011

Posted By: Ruthie Miller

Read the full article →