<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.inetium.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Andrew Zimmer</title><link>http://blogs.inetium.com/blogs/azimmer/default.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Collapsible Forms in CRM 4.0 - Defaulting to Collapsed</title><link>http://blogs.inetium.com/blogs/azimmer/archive/2010/03/14/collapsible-forms-in-crm-4-0.aspx</link><pubDate>Sun, 14 Mar 2010 19:54:00 GMT</pubDate><guid isPermaLink="false">7346ef18-9fb1-4a4e-be41-9add5078176c:28925</guid><dc:creator>Andrew Zimmer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/rsscomments.aspx?PostID=28925</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/commentapi.aspx?PostID=28925</wfw:comment><comments>http://blogs.inetium.com/blogs/azimmer/archive/2010/03/14/collapsible-forms-in-crm-4-0.aspx#comments</comments><description>&lt;p&gt;I recently discovered a new blog by Microsoft MVP, Marco Amoeda, &lt;a target="_blank" href="http://marcoamoedo.com/blog/"&gt;http://marcoamoedo.com/blog/&lt;/a&gt;.&amp;nbsp; It is quickly becoming one of my favorites.&amp;nbsp; In one posts he shows how to add collapsible forms in CRM 4.0, a feature that isn&amp;#39;t available out-of-the-box until CRM 5.&amp;nbsp; &lt;a href="http://marcoamoedo.com/blog/collapsable-form-sections-ndash-a-bit-of-the-future-in-crm-4/%20"&gt;http://marcoamoedo.com/blog/collapsable-form-sections-ndash-a-bit-of-the-future-in-crm-4/ &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I tweaked the code to collapse a section by default if the section does not contain any information.&amp;nbsp; The example I use is a billing address.&amp;nbsp; If 90% of the time you don&amp;#39;t have a billing address then you probably don&amp;#39;t want it to take up real estate on the form.&amp;nbsp; The JavaScript checks to see if any useful information is entered in the Billing Address section.&amp;nbsp; If any fields contain data then it shows the section as expanded by default, otherwise, it is collapsed.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Billing Address Section with No Data&lt;br /&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/collapse1.png"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/collapse1.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Billing Address Section with Data&lt;/b&gt;&lt;br /&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/collapse2.png"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/collapse2.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Code is also available for download below.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;function IsNullOrEmptyString(obj)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; if(obj == null || obj == &amp;quot;&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;br /&gt;&amp;nbsp;&amp;nbsp; else &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return false;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;function ShouldCollapseSection(sectionName)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; if(sectionName == &amp;quot;Billing Address&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(IsNullOrEmptyString(crmForm.all.address2_line1.DataValue) &amp;amp;&amp;amp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IsNullOrEmptyString(crmForm.all.address2_line2.DataValue) &amp;amp;&amp;amp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IsNullOrEmptyString(crmForm.all.address2_line3.DataValue) &amp;amp;&amp;amp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IsNullOrEmptyString(crmForm.all.address2_city.DataValue) &amp;amp;&amp;amp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IsNullOrEmptyString(crmForm.all.address2_stateorprovince.DataValue) &amp;amp;&amp;amp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IsNullOrEmptyString(crmForm.all.address2_postalcode.DataValue) &amp;amp;&amp;amp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IsNullOrEmptyString(crmForm.all.address2_country.DataValue) &amp;amp;&amp;amp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IsNullOrEmptyString(crmForm.all.address2_telephone1.DataValue))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return false;&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/b&gt;&lt;b&gt;return false;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;}&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;function getElementsByCondition(condition, container) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; container = container || document;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var all = container.all || container.getElementsByTagName(&amp;#39;*&amp;#39;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var arr = [];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (var k = 0; k &amp;lt; all.length; k++) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var elm = all[k];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (condition(elm, k))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; arr[arr.length] = elm;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return arr;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function attachCollapsableToSections() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var sections = getElementsByCondition(function (elm) { if (elm.className.indexOf(&amp;quot;ms-crm-Form-Section&amp;quot;) != -1) return true; }, null);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (var i = 0; i &amp;lt; sections.length; i++) {&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sections&lt;img src="http://blogs.inetium.com/emoticons/emotion-55.gif" alt="Idea" /&gt;.innerHTML = &amp;#39;&amp;lt;img&amp;nbsp; alt=&amp;quot;Expanded, click to collapse&amp;quot; src=&amp;quot;/_imgs/navup.gif&amp;quot; style=&amp;quot;cursor:hand;&amp;quot;/&amp;gt;&amp;#39; + sections&lt;img src="http://blogs.inetium.com/emoticons/emotion-55.gif" alt="Idea" /&gt;.innerHTML;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sections&lt;img src="http://blogs.inetium.com/emoticons/emotion-55.gif" alt="Idea" /&gt;.childNodes[0].attachEvent(&amp;#39;onclick&amp;#39;, toggleVisibility);&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(ShouldCollapseSection(sections&lt;img src="http://blogs.inetium.com/emoticons/emotion-55.gif" alt="Idea" /&gt;.parentNode.innerText))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var sectionContainer2 = sections&lt;img src="http://blogs.inetium.com/emoticons/emotion-55.gif" alt="Idea" /&gt;.parentNode.parentNode;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; toggleVisibilityI(sectionContainer2, sections&lt;img src="http://blogs.inetium.com/emoticons/emotion-55.gif" alt="Idea" /&gt;.childNodes[0])&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function toggleVisibilityI(sectionContainer, srcElement)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var elements = getElementsByCondition(function (elm) { if (elm.vAlign == &amp;quot;top&amp;quot;) return true; }, sectionContainer);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (var i = 0; i &amp;lt; elements.length; i++) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (elements&lt;img src="http://blogs.inetium.com/emoticons/emotion-55.gif" alt="Idea" /&gt;.style.display == &amp;quot;none&amp;quot;) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; elements&lt;img src="http://blogs.inetium.com/emoticons/emotion-55.gif" alt="Idea" /&gt;.style.display = &amp;quot;&amp;quot;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; srcElement.src = srcElement.src.replace(&amp;quot;navdown&amp;quot;, &amp;quot;navup&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; elements&lt;img src="http://blogs.inetium.com/emoticons/emotion-55.gif" alt="Idea" /&gt;.style.display = &amp;quot;none&amp;quot;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; srcElement.src = srcElement.src.replace(&amp;quot;navup&amp;quot;, &amp;quot;navdown&amp;quot;); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function toggleVisibility(e) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var sectionContainer = e.srcElement.parentNode.parentNode.parentNode;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; toggleVisibilityI(sectionContainer, e.srcElement)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;attachCollapsableToSections();&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Thanks again for a great post by Marco Amoeda!&lt;/p&gt;
&lt;p&gt;-Andrew&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Disclaimer:&amp;nbsp; This customizations is not supported by Microsoft.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.inetium.com/aggbug.aspx?PostID=28925" width="1" height="1"&gt;</description><enclosure url="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.02.89.25/Collapsed-Section2.txt" length="2747" type="text/plain" /><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/CRM+4.0/default.aspx">CRM 4.0</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/JScript/default.aspx">JScript</category></item><item><title>CRM Essential Webinar - Using the SDK to Optimize CRM Forms</title><link>http://blogs.inetium.com/blogs/azimmer/archive/2010/03/06/crm-essential-webinar-using-the-sdk-to-optimize-crm-forms.aspx</link><pubDate>Sat, 06 Mar 2010 15:59:00 GMT</pubDate><guid isPermaLink="false">7346ef18-9fb1-4a4e-be41-9add5078176c:28923</guid><dc:creator>Andrew Zimmer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/rsscomments.aspx?PostID=28923</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/commentapi.aspx?PostID=28923</wfw:comment><comments>http://blogs.inetium.com/blogs/azimmer/archive/2010/03/06/crm-essential-webinar-using-the-sdk-to-optimize-crm-forms.aspx#comments</comments><description>&lt;p style="margin:0in 0in 0.0001pt;"&gt;This past Wednesday, Bill Goergen and I gave a webinar on using the SDK to optimize the CRM form.&amp;nbsp; The webinar is available for download.&amp;nbsp; &lt;/p&gt;
&lt;p style="margin:0in 0in 0.0001pt;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0in 0in 0.0001pt;"&gt;&lt;a target="_blank" href="http://www.crmmn.com/CRM%20Essentials%20Webinar%20Recordings/CRM%20Forms%20Optimization%20-%20Andrew%20Zimmer%20and%20Bill%20Goergen%20-%20March%203,%202010.wmv"&gt;Download Webinar&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="margin:0in 0in 0.0001pt;"&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/downloadbutton.png"&gt;&lt;/a&gt;&lt;a href="http://www.crmmn.com/CRM%20Essentials%20Webinar%20Recordings/CRM%20Forms%20Optimization%20-%20Andrew%20Zimmer%20and%20Bill%20Goergen%20-%20March%203,%202010.wmv"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/downloadbutton2.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="margin:0in 0in 0.0001pt;"&gt;&lt;i&gt;&lt;b&gt;&lt;span style="font-size:13.5pt;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;color:#cc0000;"&gt;&lt;br /&gt;CRM Essentials Webinar Series&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0in 0in 0.0001pt;"&gt;&lt;i&gt;&lt;b&gt;&lt;span style="font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;color:#cc0000;"&gt;Short sessions packed with relevant and
exciting topics in Microsoft Dynamics CRM.&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0in 0in 0.0001pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0in 0in 0.0001pt;"&gt;&lt;b&gt;&lt;span style="font-size:13.5pt;color:#333333;"&gt;Using the SDK to Optimize CRM Forms&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;What and how information is captured and displayed on the CRM forms is
one of the key factors driving adoption and user satisfaction. While
the ability to configure and modify the forms using the out-of-the-box
capabilities are impressive, with a little help from the SDK (Software
Development Kit), you can dramatically enhance both functionality and
the end user experience.&lt;br /&gt;
&lt;br /&gt;The items demonstrated include functionality written by
Inetium along with functionality provided by others within the Dynamics CRM
developer community (blogs and forums).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Using collapsible sections to improve the usability of the form&lt;/li&gt;
&lt;li&gt;Auto-populating data on the CRM form to save the user time during data entry&lt;/li&gt;
&lt;li&gt;Hiding or exposing individual fields based on the users security role&lt;/li&gt;
&lt;li&gt;Dynamically modifying field requirement levels&lt;/li&gt;
&lt;li&gt;Options for displaying related entities on forms&lt;/li&gt;
&lt;li&gt;Calculating weighted revenue based on sales stage or likelihood to close (form level mathematics)&lt;/li&gt;
&lt;li&gt;Using Tool Tips to improve the quality of data capture&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;More information on other CRM Essentials sessions are available at &lt;a href="http://www.crmmn.com"&gt;http://www.crmmn.com&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.inetium.com/aggbug.aspx?PostID=28923" width="1" height="1"&gt;</description><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/CRM+4.0/default.aspx">CRM 4.0</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/form+scripting/default.aspx">form scripting</category></item><item><title>Environment-Aware Custom Workflow Configuration</title><link>http://blogs.inetium.com/blogs/azimmer/archive/2010/03/01/environment-aware-custom-workflow-configuration.aspx</link><pubDate>Mon, 01 Mar 2010 12:31:00 GMT</pubDate><guid isPermaLink="false">7346ef18-9fb1-4a4e-be41-9add5078176c:28921</guid><dc:creator>Andrew Zimmer</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/rsscomments.aspx?PostID=28921</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/commentapi.aspx?PostID=28921</wfw:comment><comments>http://blogs.inetium.com/blogs/azimmer/archive/2010/03/01/environment-aware-custom-workflow-configuration.aspx#comments</comments><description>&lt;p&gt;One of the major pains with custom workflows is storing configuration information, especially configuration data that is specific to the environment dev/stage/production.&amp;nbsp; There are a couple options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use a custom entity to store configuration information and retrieve the records during the execution of the workflow.&amp;nbsp; 
&lt;ul&gt;
&lt;li&gt;Advantages &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Allows flexibility for adding new configuration settings &lt;/li&gt;
&lt;li&gt;The settings are located within CRM, so there are less points of failure.&amp;nbsp; &lt;/li&gt;
&lt;li&gt;Has the ability to store more secure configuration settings, but security must be locked down correctly so non-administrators have no access to the data.&amp;nbsp; Also, you must ensure that the web service calls runs as an administrator user and not under the originating callers context.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Disadvantages &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Is the most work to develop and deploy.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use the input parameters of the custom workflow to store configuration information&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Advantages
&lt;ul&gt;
&lt;li&gt;It is the easiest to configure and deploy.&amp;nbsp; &lt;/li&gt;
&lt;li&gt;There is no extra deployment of files to worry about and no need to create extra entities.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Disadvantages
&lt;ul&gt;
&lt;li&gt;Anyone can see the configuration setting, even non-privileged CRM users, so don&amp;#39;t use it for passwords.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A third option is to use a config file by manually loading it from a file location on the CRM server.&amp;nbsp; One can specify the path of this config file in an input parameter if need be.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Configuration config = ConfigurationManager.OpenExeConfiguration(&amp;quot;C:\\myconfig.config&amp;quot;);&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;To use this option the config file must be deployed to every CRM server in the server farm and the file needs read access to the async service&amp;#39;s account. Click here for more information: &lt;a target="_blank" title="http://social.microsoft.com/Forums/en-US/crmdevelopment/thread/9d858c5d-0a31-4aaf-a1a0-195b89cb1100/" href="http://social.microsoft.com/Forums/en-US/crmdevelopment/thread/9d858c5d-0a31-4aaf-a1a0-195b89cb1100/"&gt;http://social.microsoft.com/Forums/en-US/crmdevelopment/thread/9d858c5d-0a31-4aaf-a1a0-195b89cb1100/&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Advantages &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;It is easier to develop code using a .Net config file.&amp;nbsp; &lt;/li&gt;
&lt;li&gt;Settings can be added and removed more quickly.&amp;nbsp; &lt;/li&gt;
&lt;li&gt;The location is more secure than input parameters.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Disadvantages &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;It is another point of failure.&amp;nbsp; &lt;/li&gt;
&lt;li&gt;Files must be deployed to the correct location and the service must have access to the file.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks to Andriy Butenko, CRM MVP for his help in identifying the alternatives to using input parameters.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Considering all the options, I usually use input parameters.&amp;nbsp; They are easy to configure and they are evident to the users.&amp;nbsp; Granted, they aren&amp;#39;t good for storing user credentials (not secure), but they do work well for passing external web service URLs, file paths to drop XML files, ect.&amp;nbsp; My biggest concern with using this method is managing settings that are environment specific.&amp;nbsp; For example, if you have a URL for a custom web service used to send data to your ERP system, you need to change it depending on if you are testing in dev, stage, or production.&amp;nbsp; Workflows can easily be deployed to production without any thought of updating an input parameter.&amp;nbsp; Before you know it, you have serious data issue because you are pushing production data to development.&amp;nbsp; Not Good!!!&lt;/p&gt;
&lt;p&gt;I am going to lay out an option for configuring all three settings within your workflow.&amp;nbsp; As opposed to putting your user/administrator in charge of pointing to dev/stage/production, your workflow will be environment-aware.&amp;nbsp; As an example, I am going to use the URL generator that is a part of the business productivity accelerator  (&lt;a target="_blank" title="http://crmaccelerators.codeplex.com/releases/view/26691" href="http://crmaccelerators.codeplex.com/releases/view/26691"&gt;http://crmaccelerators.codeplex.com/releases/view/26691&lt;/a&gt;).&amp;nbsp; &lt;/p&gt;
&lt;p&gt;The URL generator, returns the URL for the
current record that can be used within a send email workflow step.&amp;nbsp; The
workflow uses input parameters, specifying the URL and the text for the
hyperlink.&amp;nbsp; As with the issues noted previously, the problem you run into is managing the URL between environments.&amp;nbsp; If you set the URL to production then users will open up production records while testing.&amp;nbsp; If you set the URL to development, then you may forget to point the URL to production when moving customizations.&lt;/p&gt;
&lt;p&gt;As a work-around I have extended the workflow to include three URLs, one for development, stage, and production.&amp;nbsp; The code then looks for keywords in the machine name that the workflow runs from.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/step6-wfII.png"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/step3-wfII.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Behind the scenes, the code uses the machine name and/or organization name to determine which URL to use.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Solution #1&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The first solution uses the machine name explicitly.&amp;nbsp; It assumes that your development server name contains the letters &amp;quot;dev&amp;#39; and the stage server name contains the letters &amp;quot;stage&amp;quot; (if you have a stage server).&amp;nbsp; If neither case is found then the production URL is used.&amp;nbsp; Note:&amp;nbsp; You may need to tweak the code depending on your environment.&amp;nbsp; If you are only using this for one CRM installation, then you could just as easily specify the entire server name for each server level.&amp;nbsp; I keep it generic so it can be used for multiple clients (with small tweaks).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private string GetURL(string machineName)&lt;br /&gt;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!string.IsNullOrEmpty(this.StageUrl) &amp;amp;&amp;amp; &lt;br /&gt;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (machineName.ToUpper().Contains(&amp;quot;STAGE&amp;quot;)))&lt;br /&gt;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return this.StageUrl;&lt;br /&gt;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (!string.IsNullOrEmpty(this.DevUrl) &amp;amp;&amp;amp;&lt;br /&gt;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (machineName.ToUpper().Contains(&amp;quot;DEV&amp;quot;)))&lt;br /&gt;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return this.DevUrl;&lt;br /&gt;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return this.ProdUrl;&lt;br /&gt;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Solution #2&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;In most cases the dev and stage orgs are on the same server, so solution #1 won&amp;#39;t work.&amp;nbsp; As a work-around, you can look for the name of the organization when determining if you are pointing to stage.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;The workflow context includes the ID of the organization so you can do a simple web service call to return the organization name.&amp;nbsp; With the name you can determine what URL to use. The below example will return the correct URL assuming the following.&amp;nbsp; The stage org name includes the letters &amp;quot;stag&amp;quot;.&amp;nbsp; If the org name does
not include the letters &amp;quot;stag&amp;quot; then it checks the server name to see if
it contains the letters &amp;quot;dev&amp;quot;.&amp;nbsp; If neither case is satisfied then the
production URL is used.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Development
&lt;ul&gt;
&lt;li&gt;Server name = inetiumcrmdev40&lt;/li&gt;
&lt;li&gt;Org name = Inetium&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Stage
&lt;ul&gt;
&lt;li&gt;Server name = inetiumcrmdev40&lt;/li&gt;
&lt;li&gt;Org name = InetiumStaging&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Production
&lt;ul&gt;
&lt;li&gt;Server name = inetiumcrm40&lt;/li&gt;
&lt;li&gt;Org name = Inetium&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;private string GetURL(string machineName, IContextService context)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!string.IsNullOrEmpty(this.StageUrl) &amp;amp;&amp;amp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (machineName.ToUpper().Contains(&amp;quot;STAG&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; || GetOrgName(context.Context.OrganizationId, context).ToUpper().Contains(&amp;quot;STAG&amp;quot;)))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return this.StageUrl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (!string.IsNullOrEmpty(this.DevUrl) &amp;amp;&amp;amp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (machineName.ToUpper().Contains(&amp;quot;DEV&amp;quot;)))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return this.DevUrl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return this.ProdUrl;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Return the org name for set id&lt;br /&gt;private string GetOrgName(Guid orgId, IContextService context)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; using(ICrmService service = context.Context.CreateCrmService())&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ColumnSet set = new ColumnSet(new string[]{&amp;quot;name&amp;quot;});&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; organization org = (organization) service.Retrieve(EntityName.organization.ToString(), orgId, set);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return org.name;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The two full solutions are available for download below.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Steps to Installation:&lt;/b&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Register one of the two attached solutions (.cs files) within a workflow assembly&lt;/li&gt;
&lt;li&gt;Restart the CRM Async Service (so CRM picks up the changes)&lt;/li&gt;
&lt;li&gt;Create a new workflow that uses the newly installed Custom Workflow&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/step1-wfII.png"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/step1-wfII.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As a first step, execute the custom workflow step to create the URL text.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/step5-wfII.png"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/step2-wfII.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Next, set the input parameters, documenting the dev, stage (if applicable), and production URL, along with the URL Text.&amp;nbsp; Be sure to include the string {0} where you want the current records ID inserted.&lt;/p&gt;
&lt;p&gt;Note:&amp;nbsp; You can also use the account name as the URL text.&amp;nbsp; In this example I used the literal string &amp;quot;Open Account&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/step6-wfII.png"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/step3-wfII.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Add a send email step.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/step4-wfII.png"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/step4-wfII.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Specify the email message content including the output parameter of the workflow step.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Note:&amp;nbsp; I kept this example very basic.&amp;nbsp; It is a good idea to include verbose information in emails, such as the name of the account, primary contact, ect.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/step2-wfII.png"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/step5-wfII.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Create a new account and test out the workflow.&amp;nbsp; Hover your mouse over the hyperlink and verify the URL.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/step3-wfII.png"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/step6-wfII.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You may be thinking to yourself that this is an awful lot of work just to keep your administrators from having to set a couple of input parameters when moving between environments.&amp;nbsp; Fair enough!&amp;nbsp; That being said, I sleep better at night knowing there is one less step to do when moving out new customizations (and one less thing that can be overlooked).&lt;/p&gt;
&lt;p&gt;You can download the two solutions in the zip file below... ...&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;p&gt;-Andrew&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.inetium.com/aggbug.aspx?PostID=28921" width="1" height="1"&gt;</description><enclosure url="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.02.89.21/Two-Solutions.zip" length="2709" type="application/zip" /><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/CRM+4.0/default.aspx">CRM 4.0</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/url+generator/default.aspx">url generator</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/custom+workflow/default.aspx">custom workflow</category></item><item><title>Caching and Form XML in CRM 4.0</title><link>http://blogs.inetium.com/blogs/azimmer/archive/2010/02/21/caching-and-form-xml-in-crm-4-0.aspx</link><pubDate>Sun, 21 Feb 2010 19:40:00 GMT</pubDate><guid isPermaLink="false">7346ef18-9fb1-4a4e-be41-9add5078176c:28915</guid><dc:creator>Andrew Zimmer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/rsscomments.aspx?PostID=28915</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/commentapi.aspx?PostID=28915</wfw:comment><comments>http://blogs.inetium.com/blogs/azimmer/archive/2010/02/21/caching-and-form-xml-in-crm-4-0.aspx#comments</comments><description>&lt;p&gt;&lt;b&gt;Determining if a field is on the form
and not read only.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;One of the coolest things about the CRM metadata is the Form
XML.&amp;nbsp; You can inspect pretty much anything within the CRM form.&amp;nbsp;
While writing the &lt;a href="http://blogs.inetium.com/blogs/azimmer/archive/2010/02/21/crm-4-0-quick-edit-page-in-silverlight.aspx"&gt;&lt;span style="color:blue;"&gt;Quick Edit&amp;nbsp;page &lt;/span&gt;&lt;/a&gt;,
I needed to disable a field in my data grid if it wasn&amp;#39;t editable in CRM.&amp;nbsp;
Here is the code to retrieve the XML configuration and determine if it is both
on the form and editable.&lt;/p&gt;
&lt;p&gt;private bool
FieldOnFormAndNotReadOnly(string entity, string attribute, CrmService service)&lt;br /&gt;{&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
RetrieveFormXmlRequest req = new RetrieveFormXmlRequest();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; req.EntityName = entityName;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RetrieveFormXmlResponse
obj = (service.Execute(req) as RetrieveFormXmlResponse);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; XmlDocument doc = new XmlDocument();&lt;br /&gt;
&amp;nbsp;&amp;nbsp; doc.LoadXml(xml);&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (XmlNode
node in doc.SelectNodes(&amp;quot;//row/cell/control[@id=&amp;#39;&amp;quot; + attribute +
&amp;quot;&amp;#39;]&amp;quot;))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(node.Attributes[&amp;quot;disabled&amp;quot;]
!= null &amp;amp;&amp;amp;&amp;nbsp;
node.Attributes[&amp;quot;disabled&amp;quot;].InnerText.ToLower() == &amp;quot;true&amp;quot;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; continue;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
return true;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
return false;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Determine When to Clear the Cache&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Caching metadata objects is very important for performance.&amp;nbsp;
The secret is to know when to clear the cache.&amp;nbsp; Fortunately CRM has
a&amp;nbsp;function that returns&amp;nbsp;a unique timestamp for the last time CRM
was&amp;nbsp;edited.&amp;nbsp; If it changed from the last time you checked, you know
to clear your cache.&amp;nbsp; In my case I use a cache object to store the last
timestamp.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;RetrieveTimestampRequest reqTimestamp =
new RetrieveTimestampRequest();&lt;br /&gt;
MetadataService metadataService = GetMetadataService();&lt;br /&gt;
RetrieveTimestampResponse resp = metadataService.Execute(reqTimestamp) as
RetrieveTimestampResponse;&lt;br /&gt;
if (HttpContext.Current.Cache[&amp;quot;LastChecked&amp;quot;] == null &amp;amp;&amp;amp;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; resp.Timestamp !=
HttpContext.Current.Cache[&amp;quot;LastChecked&amp;quot;].ToString())&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // Clear Cache&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;p&gt;-Andrew&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.inetium.com/aggbug.aspx?PostID=28915" width="1" height="1"&gt;</description><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/CRM+4.0/default.aspx">CRM 4.0</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/Caching/default.aspx">Caching</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/RetrieveTimestampResponse/default.aspx">RetrieveTimestampResponse</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/RetrieveFormXmlResponse/default.aspx">RetrieveFormXmlResponse</category></item><item><title>CRM 4.0 Quick Edit Page in Silverlight</title><link>http://blogs.inetium.com/blogs/azimmer/archive/2010/02/21/crm-4-0-quick-edit-page-in-silverlight.aspx</link><pubDate>Sun, 21 Feb 2010 19:37:00 GMT</pubDate><guid isPermaLink="false">7346ef18-9fb1-4a4e-be41-9add5078176c:28914</guid><dc:creator>Andrew Zimmer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/rsscomments.aspx?PostID=28914</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/commentapi.aspx?PostID=28914</wfw:comment><comments>http://blogs.inetium.com/blogs/azimmer/archive/2010/02/21/crm-4-0-quick-edit-page-in-silverlight.aspx#comments</comments><description>&lt;p&gt;&lt;a target="_blank" href="http://www.youtube.com/watch?v=c8fztLxmmSw" title="Click for a video demo on YouTube"&gt;Click for a video demo on YouTube&lt;/a&gt;&lt;br /&gt;&lt;a target="_blank" href="http://www.youtube.com/watch?v=c8fztLxmmSw"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/DemoIcon.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Working on CRM extensions, I spend a lot time finding ways to make users more productive in CRM.&amp;nbsp; Sometimes its providing more information within one screen.&amp;nbsp; Other times its writing a plugin to eliminate a few clicks.&amp;nbsp; Recently I had a request to provide a quick way to edit multiple records without opening another screen.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;In my spare time I wrote a page in Silverlight to allow a user to quick-edit fileds using an Excel-like data grid.&amp;nbsp; The user can double-click a cell and edit the field.&amp;nbsp; After clicking off of the row, the record is saved to CRM.&lt;/p&gt;
&lt;p&gt;The page leverages existing configuration within CRM.&amp;nbsp; You can select a view to edit fields withing a CRM view or you can create your own personal view that includes fields that you commonly edit.&amp;nbsp;&amp;nbsp; You are only able to edit fields that both exist on the corresponding CRM form and set as editable (not read-only).&amp;nbsp; It also prevent users from editing a field that is a part of&amp;nbsp;another entity.&amp;nbsp; For example, if you add the primary contact&amp;#39;s email address on&amp;nbsp;an account view, it&amp;#39;s not editable.&amp;nbsp; This is&amp;nbsp;in an effort&amp;nbsp;to prevent the user from editing a field they assume is a part of the account record. &amp;nbsp;Eventually, I look to make the fields that are editable application-configurable.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Disclaimer:&amp;nbsp; This does not enforce business rules that are applied in client script.&amp;nbsp; Also, it doesn&amp;#39;t prevent users from editing inactive records.&amp;nbsp; However, an error will be returned when the record is saved.&lt;/p&gt;
&lt;p&gt;Currently I support the main attribute types other than lookups (future version).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;nvarchar&lt;/li&gt;
&lt;li&gt;picklist&lt;/li&gt;
&lt;li&gt;bit&lt;/li&gt;
&lt;li&gt;int&lt;/li&gt;
&lt;li&gt;float&lt;/li&gt;
&lt;li&gt;decimal&lt;/li&gt;
&lt;li&gt;money&lt;/li&gt;
&lt;li&gt;ntext&lt;/li&gt;
&lt;li&gt;datetime (both date and date time)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;Editing Date&lt;/b&gt;&lt;br /&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/QuickEditDate.png"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/QuickEditDate.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Editing Money Attribute&lt;br /&gt;&lt;/b&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/QuickEditMoney.png"&gt;&lt;b&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/QuickEditMoney.png" border="0" alt="" /&gt;&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Editing Bit Attribute&lt;br /&gt;&lt;/b&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/QuickEditBit.png"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/QuickEditBit.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Editing Picklist Attribute&lt;br /&gt;&lt;/b&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/QuickEditPickList.png"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/QuickEditPickList.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Editing String Attribute&lt;br /&gt;&lt;/b&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/QuickEditString.png"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/QuickEditString.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re interested in having us build something like this for you, contact your account executive directly or email &lt;a href="mailto:sales@inetium.com" title="sales@inetium.com"&gt;&lt;span style="color:#3366cc;"&gt;sales@inetium.com&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;-Andrew&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.inetium.com/aggbug.aspx?PostID=28914" width="1" height="1"&gt;</description><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/CRM+4.0/default.aspx">CRM 4.0</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/quick+edit/default.aspx">quick edit</category></item><item><title>Available Plugin Messages for a Given Entity in CRM 4.0</title><link>http://blogs.inetium.com/blogs/azimmer/archive/2010/02/15/available-plugin-messages-for-a-given-entity-in-crm-4-0.aspx</link><pubDate>Mon, 15 Feb 2010 13:00:00 GMT</pubDate><guid isPermaLink="false">7346ef18-9fb1-4a4e-be41-9add5078176c:28906</guid><dc:creator>Andrew Zimmer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/rsscomments.aspx?PostID=28906</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/commentapi.aspx?PostID=28906</wfw:comment><comments>http://blogs.inetium.com/blogs/azimmer/archive/2010/02/15/available-plugin-messages-for-a-given-entity-in-crm-4-0.aspx#comments</comments><description>&lt;p&gt;When I get an unusual plugin request from one of our business analysts, the first thing I ask myself is, &amp;quot;Do they have a message I can 

hijack?&amp;quot;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;With the plugin registration tool, you specify your message first and then the second field filters by what entities support the 

message.&amp;nbsp; That isn&amp;#39;t very useful when you want to determine what messages are available for a given entity.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;I found this useful query on eggheadcafe, posted by Ajith of Microsoft.&amp;nbsp; &lt;a target="_blank" title="http://www.eggheadcafe.com/software/aspnet/31684630/plugin-for-closeopen-opp.aspx" href="http://www.eggheadcafe.com/software/aspnet/31684630/plugin-for-closeopen-
opp.aspx"&gt;http://www.eggheadcafe.com/software/aspnet/31684630/plugin-for-closeopen-opp.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Just specify the entity name run the query...&amp;nbsp; Hook up the event and start debugging...&amp;nbsp; Hopefully the message is what you 

are looking for!&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;select m.name as &amp;#39;Name Of Method&amp;#39;,&lt;br /&gt;CASE m.availability&lt;br /&gt;WHEN &amp;#39;0&amp;#39; THEN &amp;#39;Server&amp;#39;&lt;br /&gt;WHEN &amp;#39;1&amp;#39; THEN &amp;#39;Offline&amp;#39;&lt;br /&gt;WHEN 

&amp;#39;2&amp;#39; THEN &amp;#39;Both&amp;#39;&lt;br /&gt;END&lt;br /&gt;as &amp;#39;MessageAvailability&amp;#39;,&lt;br /&gt;CASE mf.availability&lt;br /&gt;WHEN &amp;#39;0&amp;#39; THEN &amp;#39;Server&amp;#39;&lt;br /&gt;WHEN &amp;#39;1&amp;#39; THEN 

&amp;#39;Offline&amp;#39;&lt;br /&gt;WHEN &amp;#39;2&amp;#39; THEN &amp;#39;Both&amp;#39;&lt;br /&gt;END&lt;br /&gt;as &amp;#39;SupportedDeploymentForEntity&amp;#39;,&lt;br /&gt;e.name as &amp;#39;PrimaryEntityName&amp;#39;,s.name as 

&amp;#39;SecondaryEntityName&amp;#39;&lt;br /&gt;from sdkmessagefilter mf inner join sdkmessage m on m.sdkmessageid =&lt;br /&gt;mf.sdkmessageid&lt;br /&gt;left outer join 

entity e on e.objecttypecode = mf.primaryobjecttypecode&lt;br /&gt;left outer join entity s on s.objecttypecode = mf.secondaryobjecttypecode&lt;br /&gt;where mf.primaryobjecttypecode &amp;lt; 10000&lt;br /&gt;and mf.primaryobjecttypecode &amp;gt;= 0 -- Includes Enity.none&lt;br /&gt;and 

mf.iscustomProcessingstepallowed = 1&lt;br /&gt;&lt;b&gt;and e.name =&amp;#39;lead&amp;#39; &lt;/b&gt;&lt;br /&gt;order by m.name, e.name&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;p&gt;-Andrew&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.inetium.com/aggbug.aspx?PostID=28906" width="1" height="1"&gt;</description><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/CRM+4.0/default.aspx">CRM 4.0</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/Plugins/default.aspx">Plugins</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/messages/default.aspx">messages</category></item><item><title>Status Codes when Deactivating Records in CRM 4.0</title><link>http://blogs.inetium.com/blogs/azimmer/archive/2010/02/08/status-codes-when-deactivating-records-in-crm-4-0.aspx</link><pubDate>Mon, 08 Feb 2010 13:11:00 GMT</pubDate><guid isPermaLink="false">7346ef18-9fb1-4a4e-be41-9add5078176c:28901</guid><dc:creator>Andrew Zimmer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/rsscomments.aspx?PostID=28901</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/commentapi.aspx?PostID=28901</wfw:comment><comments>http://blogs.inetium.com/blogs/azimmer/archive/2010/02/08/status-codes-when-deactivating-records-in-crm-4-0.aspx#comments</comments><description>&lt;p&gt;When deactivating a record in CRM you need to specify a state code and a status code.&amp;nbsp; Here is the code to deativate a custom entity.&amp;nbsp; For system entities there are specific objects for each entity, i.e. SetStateOpportunityRequest.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SetStateDynamicEntityRequest deactivate = new SetStateDynamicEntityRequest();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; deactivate.Entity = new Moniker(&amp;quot;new_job&amp;quot;, id);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; deactivate.State = &amp;quot;Inactive&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; deactivate.Status = 2;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SetStateDynamicEntityResponse resp = (SetStateDynamicEntityResponse)service.Execute(deactivate);&lt;/p&gt;
&lt;p&gt;To get the State and Status you can open the StatusCode attribute and select the status drop down to see the status codes available for each state.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/StatusCode2232.gif"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/StatusCode2232.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Another option is to view the status codes from a SQL query.&amp;nbsp; It displays all the combination all in one place.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;StateCode/Status Code Query&lt;/b&gt;&lt;br /&gt;select Entity.Name, &lt;br /&gt;stringmapstatuscode.value as statusstring,&lt;br /&gt;&amp;nbsp;stringmapstatecode.value as statestring,&lt;br /&gt;&amp;nbsp;statusmap.status&lt;br /&gt;from StatusMap&lt;br /&gt;JOIN stringmap stringmapstatuscode on StatusMap.status = stringmapstatuscode.AttributeValue&lt;br /&gt;and stringmapstatuscode.ObjectTypeCode = StatusMap.ObjectTypeCode&lt;br /&gt;and stringmapstatuscode.attributename = &amp;#39;statuscode&amp;#39;&lt;br /&gt;JOIN stringmap stringmapstatecode on StatusMap.state = stringmapstatecode.AttributeValue&lt;br /&gt;and stringmapstatecode.ObjectTypeCode = StatusMap.ObjectTypeCode&lt;br /&gt;and stringmapstatecode.attributename = &amp;#39;statecode&amp;#39;&lt;br /&gt;JOIN Entity on Entity.ObjectTypeCode = stringmapstatuscode.ObjectTypeCode &lt;br /&gt;where &lt;br /&gt;Entity.Name = &amp;#39;new_job&amp;#39;&lt;br /&gt;order by StatusMap.state, statusmap.status&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/StatusCode2234.gif"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/StatusCode2234.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;p&gt;-Andrew&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.inetium.com/aggbug.aspx?PostID=28901" width="1" height="1"&gt;</description><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/CRM+4.0/default.aspx">CRM 4.0</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/Plugins/default.aspx">Plugins</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/SDK/default.aspx">SDK</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/deactivate/default.aspx">deactivate</category></item><item><title>An Argument for Asynchronous Plugins in CRM 4.0</title><link>http://blogs.inetium.com/blogs/azimmer/archive/2010/02/01/an-argument-for-asynchronous-plugins-in-crm-4-0.aspx</link><pubDate>Mon, 01 Feb 2010 12:41:00 GMT</pubDate><guid isPermaLink="false">7346ef18-9fb1-4a4e-be41-9add5078176c:28898</guid><dc:creator>Andrew Zimmer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/rsscomments.aspx?PostID=28898</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/commentapi.aspx?PostID=28898</wfw:comment><comments>http://blogs.inetium.com/blogs/azimmer/archive/2010/02/01/an-argument-for-asynchronous-plugins-in-crm-4-0.aspx#comments</comments><description>&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;One of the least used platform extensions is the asynchronous plugin.&amp;nbsp; When people think of&amp;nbsp;a process that needs to update the database that needs to run in the background, people think custom workflow.&amp;nbsp; As a CRM developer, I consider the asynchronous plugin first.&amp;nbsp; Then I think custom workflow.&amp;nbsp; Here is the argument for each.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;When to Use an Asynchronous Plugin?&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:black;font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;mso-bidi-font-size:9.0pt;"&gt;&lt;span style="mso-list:Ignore;"&gt;&amp;middot;&lt;span style="font:7pt &amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;You want the code to run under the current user&amp;#39;s credentials or a set user&amp;#39;s credentials.&amp;nbsp; Workflows run under the service account&amp;#39;s credentials.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:black;font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;mso-bidi-font-size:9.0pt;"&gt;&lt;span style="mso-list:Ignore;"&gt;&amp;middot;&lt;span style="font:7pt &amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;If you have want to store configuration information that is confidential such as a username/password. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:black;font-family:&amp;#39;Courier New&amp;#39;;mso-fareast-font-family:&amp;#39;Courier New&amp;#39;;mso-bidi-font-size:9.0pt;"&gt;&lt;span style="mso-list:Ignore;"&gt;o&lt;span style="font:7pt &amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Plugins store their configuration in a secure location.&amp;nbsp; It is set and viewed through the plugin registration tool.&amp;nbsp; Only deployment admins can see it, so you don&amp;#39;t have to worry about the credentials being compromised (at least not by very many people).&amp;nbsp; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;b&gt;Secure Plugin Registration&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/plugin4444.gif"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/plugin4444.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;b&gt;Not So Secure Custom Workflow (assuming using something sensitive for Input Parameters)&lt;br /&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/wf2222.gif"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/wf2222.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:black;font-family:&amp;#39;Courier New&amp;#39;;mso-fareast-font-family:&amp;#39;Courier New&amp;#39;;mso-bidi-font-size:9.0pt;"&gt;&lt;span style="mso-list:Ignore;"&gt;o&lt;span style="font:7pt &amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;If you stored the credentials in input parameters to a custom workflow step, anyone could see them.&amp;nbsp; Not good!&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:black;font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;mso-bidi-font-size:9.0pt;"&gt;&lt;span style="mso-list:Ignore;"&gt;&amp;middot;&lt;span style="font:7pt &amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;I like using asynchronous workflows because they are setup using the plugin registration tool.&amp;nbsp; You don&amp;#39;t have to worry about someone accidentally un-publish a workflow.&amp;nbsp; &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;When to use&amp;nbsp;a Custom Workflow?&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:black;font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;mso-bidi-font-size:9.0pt;"&gt;&lt;span style="mso-list:Ignore;"&gt;&amp;middot;&lt;span style="font:7pt &amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;Useful when you want to do something the current user does not have the security to.&amp;nbsp; Custom workflows run under a super admin account, so it can often times do more than the current user.&amp;nbsp; For example, you may want to use a custom workflow if the calling user doesn&amp;#39;t have delete authority, but you want to delete a record when someone updated a bit field to true on another record.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:black;font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;mso-bidi-font-size:9.0pt;"&gt;&lt;span style="mso-list:Ignore;"&gt;&amp;middot;&lt;span style="font:7pt &amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Custom workflows are&amp;nbsp;great If the code is reusable.&amp;nbsp; If the logic does something common like adding the current user to a team or formatting a string property as a URL, then use a custom workflow.&amp;nbsp; The code can be called in multiple places by out-of-box workflows.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:black;font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;mso-bidi-font-size:9.0pt;"&gt;&lt;span style="mso-list:Ignore;"&gt;&amp;middot;&lt;span style="font:7pt &amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Custom workflows are also great for formatting the section of an email.&amp;nbsp; For example, if you want to display derived information in an email, such as a list of all orders for a customer worth more than 100 dollars, you can pass the formatted HTML string as an output parameter.&amp;nbsp; Your business analyst can drop that output parameter into an email in an out-of-the-box workflow.&amp;nbsp; You don&amp;#39;t have to spend time formatting the entire email with simple properties and plain text.&amp;nbsp; Plus, if someone decides they want to change the content or header of the email, you don&amp;#39;t need to update the .Net code.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;b&gt;Summary&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Asynchronous plugins work the same way as custom workflows.&amp;nbsp; They run in the background.&amp;nbsp; If you have one that kicks off on save either will not stop the user from going on with their day while your process runs.&amp;nbsp; Both show up in the system jobs next to workflows.&amp;nbsp; &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;When deciding whether to use custom workflows or asynchronous plugins, I weigh the advantages and disadvantages of each for the specific scenario.&amp;nbsp; If I ever had a tie, I&amp;#39;d probably go with the asynchronous plugin, but&amp;nbsp;I haven&amp;#39;t seen a tie yet.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;-Andrew&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.inetium.com/aggbug.aspx?PostID=28898" width="1" height="1"&gt;</description><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/CRM+4.0/default.aspx">CRM 4.0</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/Plugins/default.aspx">Plugins</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/asynchronous+plugins/default.aspx">asynchronous plugins</category></item><item><title>Plugin Best Practices in CRM 4.0</title><link>http://blogs.inetium.com/blogs/azimmer/archive/2010/01/25/plugin-best-practices-in-crm-4-0.aspx</link><pubDate>Mon, 25 Jan 2010 11:56:00 GMT</pubDate><guid isPermaLink="false">7346ef18-9fb1-4a4e-be41-9add5078176c:28895</guid><dc:creator>Andrew Zimmer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/rsscomments.aspx?PostID=28895</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/commentapi.aspx?PostID=28895</wfw:comment><comments>http://blogs.inetium.com/blogs/azimmer/archive/2010/01/25/plugin-best-practices-in-crm-4-0.aspx#comments</comments><description>&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;When it comes to writing plugins, there are three driving factors.&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:black;font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;mso-bidi-font-size:9.0pt;"&gt;&amp;middot;&lt;/span&gt;&lt;span style="font-size:7pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:Symbol;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Quality - If you don&amp;#39;t follow best practices you will find defects in production.&amp;nbsp; The defects are usually challenging to troubleshoot.&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:black;font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;mso-bidi-font-size:9.0pt;"&gt;&amp;middot;&lt;/span&gt;&lt;span style="font-size:7pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:Symbol;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Performance - You are working with web services that can only update/insert/delete one record at&amp;nbsp;time.&amp;nbsp; You have database records with 50+ columns that are retrieved over web services.&amp;nbsp; It isn&amp;#39;t surprising that if you don&amp;#39;t develop your software optimally, you will have overall system slowness.&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:black;font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;mso-bidi-font-size:9.0pt;"&gt;&amp;middot;&lt;/span&gt;&lt;span style="font-size:7pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:Symbol;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Maintainability - You are working with dynamic entities that contain a bag of generic properties.&amp;nbsp; You tend to see a great deal of casting to different CRM types.&amp;nbsp; It doesn&amp;#39;t take very long before your data access code becomes cluttered with business logic.&amp;nbsp; Your code can start looking like spaghetti&amp;nbsp;very quickly.&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;I wanted to lay out some best practices that help honor these driving factors.&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;new AllColumns() == BAD &amp;amp;&amp;amp; new AllColumns() != GOOD&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-size:20.5pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-font-weight:bold;"&gt;Never return all columns from the web service.&amp;nbsp; Never!&amp;nbsp; Even a basic entity contains 20+ columns.&amp;nbsp; This takes a long time to make its way from the database and into your plugin.&amp;nbsp; Only return the fields that you need a fresh copy of.&amp;nbsp; If you will commonly return a set of columns, keep a member-level variable with a string array.&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size:13.5pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-font-weight:bold;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-font-weight:bold;"&gt;Note:&amp;nbsp; One thing to watch out for when using a ColumnSet....&amp;nbsp; You may return a dynamic entity and check to see if the property bag exists in a field.&amp;nbsp; If it doesn&amp;#39;t exist then it is assumed to be null in the database.&amp;nbsp; If you forgot to specify it in the ColumnSet you may get a false negative.&lt;/span&gt;&lt;span style="font-size:13.5pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-font-weight:bold;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Code with ColumnSet Specified&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/plugin3323.gif"&gt;&lt;b style="mso-bidi-font-weight:normal;"&gt;&lt;span style="font-size:9pt;color:blue;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;text-decoration:none;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;mso-no-proof:yes;text-underline:none;"&gt; &lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/plugin3323.gif"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/plugin3323.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;b&gt;&lt;span style="font-size:13.5pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Only Update Fields you Are Changing&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Only send the fields you are changing to the database.&amp;nbsp; For example, let&amp;rsquo;s say you are doing a retrieve multiple, returning back 20 columns.&amp;nbsp; Then you update one CrmBoolean field and call service.Update.&amp;nbsp; It will send all 20 columns across the network.&amp;nbsp; This hurts performance.&amp;nbsp; It can also cause inadvertent results.&amp;nbsp; Even though you didn&amp;#39;t change 19 of the fields, it will trigger a change on all 20 columns.&amp;nbsp; If you have a workflow or plugin that looks for these fields to change, it can cause infinite loops.&amp;nbsp; In the very least, you will have some extra records.&amp;nbsp; This can happen if you have an out-of-the-box workflow that looks for an &amp;quot;EmailToCustomer&amp;quot; CrmBoolean being updated to true.&amp;nbsp; If you sent this field to the database, it will fire.&amp;nbsp; Now you have duplicate emails being sent even though you didn&amp;rsquo;t actually change the field.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;You have a couple of options to ensure that you only send what is changing to the database.&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;1)&amp;nbsp; Keep a separate copy of things you want to update.&amp;nbsp; I have a helper function that returns a dynamic entity what only its key field.&amp;nbsp; You can add&amp;nbsp;properties to the property bag and send them to the web service.&amp;nbsp; Don&amp;#39;t just update the DynamicEntity that was returned from the web service.&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;internal static DynamicEntity GetBlankEntity(string entityName, string primaryKeyAttribute, Guid id)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DynamicEntity entity = new DynamicEntity(entityName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; entity.Properties[primaryKeyAttribute] = new Key(id);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return entity;&lt;br /&gt;}&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;DynamicEntity entity = CRMUtilities.GetBlankEntity(&amp;quot;new_job&amp;quot;, &amp;quot;new_jobid&amp;quot;, id);&lt;br /&gt;entity.Properties[&amp;quot;new_jobcompleted&amp;quot;] = new CrmBoolean(true);&lt;br /&gt;service.Update(entity);&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;2)&amp;nbsp; You can build it into your ORM, so it keeps a separate copy of a dynamic entity with changes.&amp;nbsp; More on this later...&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Encapsulate the Extraction of Properties&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;One of the easiest ways to create a bug is to extract properties manually using casting.&amp;nbsp; Check out this code.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Lookup custLookup = entity.Properties[&amp;quot;customerid&amp;quot;] as Lookup;&lt;br /&gt;Guid custId = custLookup.Value;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;It looks like solid code right?&amp;nbsp; Well, you will actually get a null reference exception here.&amp;nbsp; The customerid field is actually a Customer property.&amp;nbsp; It can be an account, contact, or lead so they have a separate object for it.&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;As with the previous section, you have two options.&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;1)&amp;nbsp; You can write a method to handle returning all Guids.&amp;nbsp; It will return a nullable Guid for Lookups, Owner, Customer, and Key.&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Helper Method&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;br /&gt;public static Guid? GetGuid(DynamicEntity entity, string propertyName)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (entity.Properties.Contains(propertyName))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Lookup lookup = entity[propertyName] as Lookup;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (lookup != null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (lookup.IsNull || lookup.IsNullSpecified)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return null;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return lookup.Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Key key = entity[propertyName] as Key;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (key != null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return key.Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Owner owner = entity[propertyName] as Owner;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (owner != null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return owner.Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Customer cust = entity[propertyName] as Customer;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (cust != null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return cust.Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return null;&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;}&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;2)&amp;nbsp; You can build your ORM to extract the properties in their respective types.&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Use an ORM (Object Relational Mapping)&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;You can help increase the quality and maintainability of your code by implementing an ORM.&amp;nbsp; I started building out my ORM by working off of the code that comes with David Yack (MVP)&amp;#39;s book &lt;a href="http://thecrmbook.com/" title="CRM as a Rapid Development Platform"&gt;&lt;span style="color:blue;"&gt;CRM as a Rapid Development Platform&lt;/span&gt;&lt;/a&gt;.&amp;nbsp; It was amazing to see that code that would eliminate 70% of my bugs.&amp;nbsp; I thought, &amp;quot;I might actually start liking this CRM thing!&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Here are the keys to a CRM ORM:&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:black;font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;mso-bidi-font-size:9.0pt;"&gt;&amp;middot;&lt;/span&gt;&lt;span style="font-size:7pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:Symbol;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Most importantly, you have an&amp;nbsp;object that maps to each DynamicEntity.&amp;nbsp; Each property in the entity maps to a field in the object. They are exposed as nullable .Net Types.&amp;nbsp; You now treat your customerid field as a nullable guild.&amp;nbsp; You know that behind the scenes there was a CRM Customer object, but you don&amp;#39;t have to deal with the inherent bugs.&amp;nbsp; This is done through code generation.&amp;nbsp; The properties are generated by using the metadata service.&amp;nbsp; You have helper methods that retrieve the nullable types from the values from the properties and store data in the properties.&amp;nbsp; You just deal with the plain old C# types.&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Sample of Generated Class&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;public int? owneridtype&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; get&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (this.Entity == null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return null;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (CTCDEPropHelper.PropertyExists(this.Entity, &amp;quot;owneridtype&amp;quot;))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return CTCDEPropHelper.GetNumberValue(this.Entity, &amp;quot;owneridtype&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return null;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; set&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (this.Entity == null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bool hasChanges = CTCDEPropHelper.AddNumberProperty(this.Entity, &amp;quot;owneridtype&amp;quot;, value);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!this.IsLoading &amp;amp;&amp;amp; hasChanges)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CTCDEPropHelper.AddNumberProperty(this.EntityChanges, &amp;quot;owneridtype&amp;quot;, value);&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;public string owneridname&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; get&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (this.Entity == null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &amp;quot;&amp;quot;;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (CTCDEPropHelper.PropertyExists(this.Entity, &amp;quot;ownerid&amp;quot;))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return CTCDEPropHelper.GetLookupPrimaryText(this.Entity, &amp;quot;ownerid&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &amp;quot;&amp;quot;;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:black;font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;mso-bidi-font-size:9.0pt;"&gt;&amp;middot;&lt;/span&gt;&lt;span style="font-size:7pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:Symbol;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;The objects keep track of fields that change, so you only send fields that change to the database.&amp;nbsp; The objects actually store two DynamicEntities.&amp;nbsp; One is the version that was returned from the web service.&amp;nbsp; The second contains only the Key field along with any changes (for updating).&amp;nbsp; The great part about this is that you can check to see if anything changed before calling an update.&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Base Object Code&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;public virtual void Save(ICrmService service)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (this.IsDirty)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (this.IsNew())&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; service.Create(this.EntityChanges);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; service.Update(EntityChanges);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:black;font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;mso-bidi-font-size:9.0pt;"&gt;&amp;middot;&lt;/span&gt;&lt;span style="font-size:7pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:Symbol;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;It allows you to follow the separation of concerns principal by keeping each layer of code in its own place. &lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;Sample Project Folder Structure&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/ORM1.gif"&gt;&lt;span style="font-size:9pt;color:blue;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;text-decoration:none;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;mso-no-proof:yes;text-underline:none;"&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/ORM1.gif"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/ORM1.gif" border="0" alt="" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:black;font-family:&amp;#39;Courier New&amp;#39;;mso-fareast-font-family:&amp;#39;Courier New&amp;#39;;mso-bidi-font-size:9.0pt;"&gt;o&lt;/span&gt;&lt;span style="font-size:7pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Keep your data access methods in their own folder, away from the actual plugin class.&amp;nbsp;&amp;nbsp;You will still need to deal with the lengthy web service retrieve multiple request objects, so let&amp;rsquo;s keep that code away from the actual plugin.&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:black;font-family:&amp;#39;Courier New&amp;#39;;mso-fareast-font-family:&amp;#39;Courier New&amp;#39;;mso-bidi-font-size:9.0pt;"&gt;o&lt;/span&gt;&lt;span style="font-size:7pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;I keep the generated objects their own folder as well.&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:black;font-family:&amp;#39;Courier New&amp;#39;;mso-fareast-font-family:&amp;#39;Courier New&amp;#39;;mso-bidi-font-size:9.0pt;"&gt;o&lt;/span&gt;&lt;span style="font-size:7pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Lastly, I create a partial class of the generated objects and I keep them in a different folder.&amp;nbsp; That way you can re-generate the objects whenever you add fields to CRM, and you don&amp;#39;t have to worry about losing your business logic code.&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Partial Class with Same Class Name as Generated Objects&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;br /&gt;public partial class inetopportunity&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; // Insert business logic code here&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Use Pre-Event Plugins When Possible &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Pre-event plugins occur before the changes are persisted to the database.&amp;nbsp; The advantage to using a pre-event plugin, particularly for Create and Update, is that you don&amp;#39;t have to update the database twice.&amp;nbsp; You can update the fields that are being updated or pass new fields into the web service save process.&amp;nbsp; This isn&amp;#39;t ideal for more complex scenarios, but if you are doing something simple such as separating a birth date fields into the day/month/year, pre-event plugins work great!&amp;nbsp; One of my favorites:&amp;nbsp; &lt;a target="_blank" href="http://blogs.msdn.com/crm/archive/2009/02/27/creating-a-birthday-contact-list.aspx" title="http://blogs.msdn.com/crm/archive/2009/02/27/creating-a-birthday-contact-list.aspx"&gt;http://blogs.msdn.com/crm/archive/2009/02/27/creating-a-birthday-contact-list.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Consider Using Asynchronous Plugins or Custom Workflows for Longer Running Processes&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;Synchronous plugins run while the user is sitting there waiting for the save to complete.&amp;nbsp; Your users&amp;#39; time is precious, so it is very important to pay attentions to the other tips I mentioned in this post.&amp;nbsp; If you followed all of them and you still have a process that runs for more than a couple seconds, consider running your code asynchronously.&amp;nbsp; This can be done using an asynchronous plugin or as a custom workflow.&amp;nbsp; For more information, stay tuned for next week&amp;#39;s blog post titled, &amp;quot;An Argument for Asynchronous Plugins.&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;-Andrew&lt;/span&gt;&lt;span style="font-size:12pt;color:black;font-family:&amp;#39;Times New Roman&amp;#39;,&amp;#39;serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9pt;color:black;font-family:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.inetium.com/aggbug.aspx?PostID=28895" width="1" height="1"&gt;</description><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/CRM+4.0/default.aspx">CRM 4.0</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/Plugins/default.aspx">Plugins</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/Workflows/default.aspx">Workflows</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/Plugin+Best+Practices/default.aspx">Plugin Best Practices</category></item><item><title>Silverlight Applications in CRM 4.0</title><link>http://blogs.inetium.com/blogs/azimmer/archive/2010/01/21/silverlight-applications-in-crm-4-0.aspx</link><pubDate>Thu, 21 Jan 2010 11:57:00 GMT</pubDate><guid isPermaLink="false">7346ef18-9fb1-4a4e-be41-9add5078176c:28893</guid><dc:creator>Andrew Zimmer</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/rsscomments.aspx?PostID=28893</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/commentapi.aspx?PostID=28893</wfw:comment><comments>http://blogs.inetium.com/blogs/azimmer/archive/2010/01/21/silverlight-applications-in-crm-4-0.aspx#comments</comments><description>&lt;p&gt;&lt;a target="_blank" title="Click for a video demo on YouTube" href="http://www.youtube.com/watch?v=adu-Ru0WbzI"&gt;Click for a video demo on YouTube&lt;/a&gt;&lt;br /&gt;&lt;a target="_blank" href="http://www.youtube.com/watch?v=adu-Ru0WbzI"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/DemoIcon.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="padding-left:60px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Over Christmas break I tackled a little technology by the name of Silverlight.&amp;nbsp; I built three basic applications that are aimed at doing the following to augment the features already available in CRM.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Provide users with access to more information within one screen&lt;/li&gt;
&lt;li&gt;Allow for an easier understanding of relationships in CRM data&lt;/li&gt;
&lt;li&gt;Provide a user interface that is user friendly &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Global Search&lt;br /&gt;&lt;/b&gt;Allow for a quick search of multiple entities in one place (account, contact, and lead).&amp;nbsp; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It displays all the record types in one grid, denoting them by their corresponding icon.&lt;/li&gt;
&lt;li&gt;Double click a record to open it in CRM&lt;/li&gt;
&lt;li&gt;Click on a lookup column to open the related record&lt;/li&gt;
&lt;li&gt;Paging is supported (Silverlight field out-of-the-box)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/Silverlight1.gif"&gt;&lt;/a&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/Silverlight7.gif"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/Silverlight7.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Technical Details&lt;/i&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Double-Click isn&amp;#39;t an event that you can easily subscribe to.&amp;nbsp;&amp;nbsp;I ended up using the Double Click manager from&amp;nbsp;&lt;a href="http://weblogs.asp.net/aboschin/archive/2008/03/17/silverlight-2-0-a-double-click-manager.aspx" title="thanks to code from Andrea Boschin"&gt;Andrea Boschin&lt;/a&gt;.&amp;nbsp; After using it for a while I noticed that it would get stuck in an infinite loop where anytime you clicked it would open up the same record three times.&amp;nbsp; Ends up that the problem was caused by the on load event for a data grid item being called multiple times during a load.&amp;nbsp; To fix this, I unhooked any existing events before adding a new event that hooked into the double-click manager.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="padding-left:60px;"&gt;private void _dataGrid1_LoadingRow(object sender, DataGridRowEventArgs e)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.Row.MouseLeftButtonUp -= _gridClickManager.HandleClick;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.Row.MouseLeftButtonUp -= _gridClickManager.HandleClick;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.Row.MouseLeftButtonUp += _gridClickManager.HandleClick;&lt;br /&gt;}&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We have data coming back from multiple entities where each field could be of a different type.&amp;nbsp; To handle this I created generic objects that allowed the client to easily bind data whether it is a PickList, LookUp, or string field.&amp;nbsp; To hook in a new entity, it is as simple as writing a couple lines of code in the WCF service.&lt;/li&gt;
&lt;li&gt;I learned the hard way that Silverlight doesn&amp;#39;t support GIF files for images.&amp;nbsp; I was hoping to simply link to the GIF files that exist under the CRM _img folder.&amp;nbsp; I ended up having to convert the files to JPG files and include them as content files in my Silverlight XAP.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Account Hierarchy&lt;br /&gt;&lt;/b&gt;Expanded on an app I wrote back in ASP.Net, by adding some new features.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The hierarchy displays accounts, sub accounts, contacts (along with sub-contacts), opportunities, and orders&lt;/li&gt;
&lt;li&gt;You can click on any of the nodes to see quick info on the record.&amp;nbsp; &lt;/li&gt;
&lt;li&gt;You can change the parenting relationships on accounts and contacts by dragging and dropping nodes. 
&lt;ul&gt;
&lt;li&gt;Drag and drop a contact over a different account and it will turn green.&amp;nbsp; Release the mouse and it will change the contact&amp;#39;s parent account field and reload the form.&lt;/li&gt;
&lt;li&gt;Drag and drop an account over a different account to change parent account.&lt;/li&gt;
&lt;li&gt;Drag and drop a contact over a different contact to change the parent contact.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/Silverlight2.gif"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/Silverlight2.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/Silverlight3.gif"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/Silverlight3.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Technical Details&lt;/i&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Being pretty new to Silverlight I didn&amp;#39;t know how to handle drag and drop functionality.&amp;nbsp; I got lucky and found a solution from a blog post&amp;nbsp;(&lt;a href="http://blogs.infosupport.com/blogs/alexb/archive/2009/09/07/A-complete-Silverlight-3-drag-and-drop-solution.aspx"&gt;http://blogs.infosupport.com/blogs/alexb/archive/2009/09/07/A-complete-Silverlight-3-drag-and-drop-solution.aspx&lt;/a&gt;). It showed you how to add drag and drop support to a textbox being dropped into a ListBox.&amp;nbsp; I enhanced it to handle a treeview where the client controls whether the current tree node is valid for dropping.&amp;nbsp; I added rules such as: 
&lt;ul&gt;
&lt;li&gt;You can only use drag and drop for contacts and accounts only&lt;/li&gt;
&lt;li&gt;Contacts can drop on either accounts or contacts&lt;/li&gt;
&lt;li&gt;Accounts can only drop on other accounts (sub-account scenario)&lt;/li&gt;
&lt;li&gt;You can&amp;#39;t drop on your current parent (wouldn&amp;#39;t change anything)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I added the quick-view feature in the right pane by adding simple stack panels for each entity type.&amp;nbsp; When the user clicks on a node it shows the correct panel and binds it.&amp;nbsp; &lt;/li&gt;
&lt;li&gt;My past account hierarchy posts have used filtered views with recursive SQL calls to increase performance.&amp;nbsp; With the added complexity of adding more entities (now includes orders and sub-contacts), it uses 100% web service calls.&amp;nbsp; The good part is that it supports CRM Online.&amp;nbsp; The bad part is that it doesn&amp;#39;t perform well&amp;nbsp;on larger tree structures.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Employee (systemuser) Org Chart&lt;br /&gt;&lt;/b&gt;Similar to the account hierarchy, the org chart changes the manager of a user.&amp;nbsp; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You are able to configure the following with one screen: 
&lt;ul&gt;
&lt;li&gt;the current user &lt;/li&gt;
&lt;li&gt;the current user&amp;#39;s direct reports&lt;/li&gt;
&lt;li&gt;the manager of the current user (going up 3 levels)&lt;/li&gt;
&lt;li&gt;the current user&amp;#39;s peers&lt;/li&gt;
&lt;li&gt;the peer&amp;#39;s direct reports&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;You can drag and drop the employee over another employee to change the user&amp;#39;s manager.&amp;nbsp; If the drop is valid, the node turns green.&lt;/li&gt;
&lt;li&gt;You can click the user node to see some quick info about the employee&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/Silverlight4.gif"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/Silverlight6.gif"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/Silverlight6.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/Silverlight5.gif"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/Silverlight5.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Technical Details&lt;/i&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I used the same drag and drop functionality with this page.&amp;nbsp; The drag and drop code that I used leverages generics, so using a different data context didn&amp;#39;t require a lot of changes.&lt;/li&gt;
&lt;li&gt;When a user drags and drops a manager, I use the SetParentSystemUserRequest API that is a part of the CRM SDK.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="padding-left:60px;"&gt;SetParentSystemUserRequest req = new SetParentSystemUserRequest();&lt;br /&gt;req.KeepChildUsers = true;&lt;br /&gt;req.ParentId = managerObj.Id;&lt;br /&gt;req.UserId = userInet.systemuserid.Value;&lt;br /&gt;serv.Execute(req);&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In the case where you demote someone to work for one of their subordinates, CRM&amp;nbsp;throws an error because the user reports to the same person who reports to them.&amp;nbsp; I had to hook into this event and change the new manager to report to the original managers&amp;#39; manager.&amp;nbsp; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&amp;rsquo;re interested in having us build something like this for you, contact your account executive directly or email &lt;a href="mailto:sales@inetium.com" title="sales@inetium.com"&gt;&lt;span style="color:#3366cc;"&gt;sales@inetium.com&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;-Andrew&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.inetium.com/aggbug.aspx?PostID=28893" width="1" height="1"&gt;</description><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/CRM+4.0/default.aspx">CRM 4.0</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/hierarchy/default.aspx">hierarchy</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/drag+and+drop/default.aspx">drag and drop</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/account+hierarchy/default.aspx">account hierarchy</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/crm+global+search/default.aspx">crm global search</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/crm+Silverlight/default.aspx">crm Silverlight</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/crm+org+chart/default.aspx">crm org chart</category></item><item><title>CRM 4.0 - Displaying a Related Entity in an IFRAME - Slightly Improved</title><link>http://blogs.inetium.com/blogs/azimmer/archive/2010/01/14/crm-displaying-related-entity-in-iframe-slightly-improved.aspx</link><pubDate>Fri, 15 Jan 2010 03:47:00 GMT</pubDate><guid isPermaLink="false">7346ef18-9fb1-4a4e-be41-9add5078176c:28885</guid><dc:creator>Andrew Zimmer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/rsscomments.aspx?PostID=28885</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/commentapi.aspx?PostID=28885</wfw:comment><comments>http://blogs.inetium.com/blogs/azimmer/archive/2010/01/14/crm-displaying-related-entity-in-iframe-slightly-improved.aspx#comments</comments><description>&lt;p&gt;When I say slightly improved, let me emphasize the word slightly... ... &lt;/p&gt;
&lt;p&gt;The code that displays related entities in an IFRAME has been around for quite a while.&amp;nbsp; For the sake of not reinventing the wheel, here it is:&amp;nbsp; &lt;a href="http://robscrm.blogspot.com/2007/11/showing-related-entities-in-iframe.html"&gt;http://robscrm.blogspot.com/2007/11/showing-related-entities-in-iframe.html&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When you render the IFRAME it doesn&amp;#39;t look as professional as a normal CRM view.&amp;nbsp; The borders have a lot of white-space and the IFRAME just looks out of place.&amp;nbsp; A while back Microsoft sent me some code that does related entities for three entities at a time in a tabbed IFRAME.&amp;nbsp; It is essentially the same things as the basic related entities IFRAME times 3 entities.&amp;nbsp; Good stuff!&lt;/p&gt;
&lt;p&gt;So, when i looked at the IFRAME I noticed that the formatting problems didn&amp;#39;t exist.&amp;nbsp; After one of our business analysts asked if I could clean up the styling on the related entity IFRAME, I decided to leverage the code.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Before Fix&lt;br /&gt;&lt;/b&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/Before-Related-Entities2.gif"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/Before-Related-Entities2.gif" border="0" alt="" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;br /&gt;After Fix&lt;br /&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/After-Related-Entities.gif"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/After-Related-Entities.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So, here is the code.&amp;nbsp; Enjoy.&lt;br /&gt;-Andrew&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; function GetFrameSource(tabSet) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (crmForm.ObjectId != null) {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var oId = crmForm.ObjectId;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var oType = crmForm.ObjectTypeCode;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var security = crmFormSubmit.crmFormSubmitSecurity.value;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &amp;quot;areas.aspx?oId=&amp;quot; + oId + &amp;quot;&amp;amp;oType=&amp;quot; + oType + &amp;quot;&amp;amp;security=&amp;quot; + security + &amp;quot;&amp;amp;tabSet=&amp;quot; + tabSet;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &amp;quot;about:blank&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp; // Waits for the content window of the IFrame to be ready&lt;br /&gt;&amp;nbsp; function FixStylingInFrameSource(iframeID) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Check the content window&amp;#39;s ready state&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (document.getElementById(iframeID).contentWindow.document.readyState&lt;br /&gt;!= &amp;quot;complete&amp;quot;) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Re-run this function in 10 ticks&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; window.setTimeout(function() { FixStylingInFrameSource(iframeID) }, 10);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Content window is ready&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Change the background color&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById(iframeID).contentWindow.document.body.style.backgroundColor = &amp;quot;#eef0f6&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Remove the left border&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById(iframeID).contentWindow.document.body.all(0).style.borderLeftStyle = &amp;quot;none&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Remove padding&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById(iframeID).contentWindow.document.body.all(0).all(0).all(0).all(0).style.padding = &amp;quot;0px&amp;quot;;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Make the cell the full width of the IFRAME&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById(iframeID).contentWindow.document.body.all(0).style.width = &amp;quot;102%&amp;quot;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Show the IFrame&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById(iframeID).style.display = &amp;quot;block&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;if(crmForm.FormType != 1)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; crmForm.all.IFRAME_contacts.src = GetFrameSource(&amp;quot;areaContacts&amp;quot;);&lt;br /&gt;&amp;nbsp; FixStylingInFrameSource(&amp;#39;IFRAME_contacts&amp;#39;);&lt;br /&gt;}&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.inetium.com/aggbug.aspx?PostID=28885" width="1" height="1"&gt;</description><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/CRM+4.0/default.aspx">CRM 4.0</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/JScript/default.aspx">JScript</category></item><item><title>Using Custom Dialogs in CRM 4.0 with Offline Client and CRM Online Support</title><link>http://blogs.inetium.com/blogs/azimmer/archive/2009/12/22/using-modal-dialogs-crm-4-0-with-offline-client-crm-online-support.aspx</link><pubDate>Tue, 22 Dec 2009 12:41:00 GMT</pubDate><guid isPermaLink="false">7346ef18-9fb1-4a4e-be41-9add5078176c:28880</guid><dc:creator>Andrew Zimmer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/rsscomments.aspx?PostID=28880</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/commentapi.aspx?PostID=28880</wfw:comment><comments>http://blogs.inetium.com/blogs/azimmer/archive/2009/12/22/using-modal-dialogs-crm-4-0-with-offline-client-crm-online-support.aspx#comments</comments><description>&lt;p&gt;When you think of CRM Online or clients that use the Offline Client, you may think that custom forms are off limits, at least without a lot of deployment hastles.&amp;nbsp; I wanted to show a simple JScript snippet that can help provide more user-friendly forms when an ASP.Net website isn&amp;#39;t an option... ...&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Problem&lt;br /&gt;&lt;/strong&gt;When the user clicks the button on a parent record for &amp;quot;Reject All&amp;quot;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prompt the user for a rejection reason&lt;/li&gt;
&lt;li&gt;Set the rejection reason on the parent record&lt;/li&gt;
&lt;li&gt;Update a rejected flag on the parent record&lt;/li&gt;
&lt;li&gt;Set the rejection reason on all child records&lt;/li&gt;
&lt;li&gt;Deactivate all child records&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;NOTE:&amp;nbsp; The forms must support the Offline Client (indirectly this would support CRM Online).&lt;/p&gt;
&lt;p&gt;Since the code needed to support the offline client, I developed the entire solution in JScript.&amp;nbsp; When the user clicks the toolbar button,&amp;nbsp;a modal dialog will prompt for the cancellation reason and JScript will do all&amp;nbsp;the work of updating the parent and child records.&amp;nbsp; No external ASP.Net forms are necessary.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Click Toolbar Button for Reject All&lt;br /&gt;&lt;/strong&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/EventBudget1.gif"&gt;&lt;img border="0" src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/EventBudget1.gif" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Enter Reject Reason &lt;br /&gt;&lt;/strong&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/EventBudget3b.gif"&gt;&lt;img border="0" src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/EventBudget3b.gif" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Before I talk about how I implemented it, I wanted to go over the less desirable options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When the user clicks the &amp;quot;Reject All&amp;quot; button, make the Cancel Reason field required on the form and prompt the user to enter it and click save.&amp;nbsp; While this will accomplish the goals, it isn&amp;#39;t as user friendly.&lt;/li&gt;
&lt;li&gt;Use a JScript prompt to retrieve the cancel reason from the user and then use JScript to update the parent and child record (i.e. var reply = prompt(&amp;quot;Please enter a reject comment.&amp;quot;, &amp;quot;&amp;quot;)).&amp;nbsp; As with the previous solution,&amp;nbsp;this will accomplish the goals, but it isn&amp;#39;t as user friendly. &lt;/li&gt;
&lt;li&gt;Use ASP.Net web forms to retrieve the cancel reason.&amp;nbsp; This will also accomplish the goal but it presents some deployment challenges for the offline client and CRM Online.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;The Solution&lt;br /&gt;&lt;/strong&gt;Begin by adding the ISV button to the toolbar.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;First, ensure that your installation is configured to allow ISV buttons for web, Outlook Client, and Offline Client.&amp;nbsp; This is done from Settings --&amp;gt; System Settings.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/EventBudget4.gif"&gt;&lt;/a&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/EventBudget4.gif"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/EventBudget4b.gif"&gt;&lt;/a&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/EventBudget4c.gif"&gt;&lt;img border="0" src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/EventBudget4c.gif" alt="" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/EventBudget5.gif"&gt;&lt;img border="0" src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/EventBudget5.gif" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Second, import the following XML to add the button.&lt;/p&gt;
&lt;p&gt;&amp;lt;ImportExportXml version=&amp;quot;4.0.0.0&amp;quot; languagecode=&amp;quot;1033&amp;quot; generatedBy=&amp;quot;OnPremise&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;Entities&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/Entities&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;Roles&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/Roles&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;Workflows&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/Workflows&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;IsvConfig&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;configuration version=&amp;quot;3.0.0000.0&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Root&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;MenuBar&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/MenuBar&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Root&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Entities&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Entity name=&amp;quot;inet_budget&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ToolBar ValidForCreate=&amp;quot;0&amp;quot; ValidForUpdate=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Button Icon=&amp;quot;/_imgs/ico_18_role_x.gif&amp;quot; JavaScript=&amp;quot;document.RejectAll();&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Titles&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Title LCID=&amp;quot;1033&amp;quot; Text=&amp;quot;Reject All&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Titles&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ToolTips&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ToolTip LCID=&amp;quot;1033&amp;quot; Text=&amp;quot;Reject All&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ToolTips&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Button&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ToolBar&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Entity&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Entities&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/configuration&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/IsvConfig&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;EntityMaps /&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;EntityRelationships /&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;Languages&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Language&amp;gt;1033&amp;lt;/Language&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/Languages&amp;gt;&lt;br /&gt;&amp;lt;/ImportExportXml&amp;gt;&lt;/p&gt;
&lt;p&gt;Notice that the JScript attached to the button simply calls a function.&amp;nbsp; I like to&amp;nbsp;use functions,&amp;nbsp;so I don&amp;#39;t have to re-import the ISV Config customization every time I want to make a simple JScript change.&amp;nbsp; I can just update the On Load for the form.&lt;/p&gt;
&lt;p&gt;Next, add the following code to OnLoad to handle the button click event.&amp;nbsp; It begins by opening a modal dialog by using some hard-coded HTML.&amp;nbsp; As opposed to deploying an ASP.Net web page to your ISV folder on the CRM Server (as well as Offline Client user&amp;#39;s machine), you are able to deploy your entire solution by importing/exporting your CRM customizations.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;br /&gt;document.RejectAll = function()&lt;br /&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;var childWindow = window.open(&amp;#39;&amp;#39;,&amp;#39;&amp;#39;,&amp;#39;menubar=no,statusbar=no,toolbar=no,width=285,height=175&amp;#39;);&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;// If its already been rejected before, take the reject comment from the form&lt;br /&gt;var currentRejectComment = &amp;quot;&amp;quot;;&lt;br /&gt;if(crmForm.all.inet_rejectcomment.DataValue != null)&lt;br /&gt;&amp;nbsp; currentRejectComment = crmForm.all.inet_rejectcomment.DataValue;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;br /&gt;var htmlText = &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;lt;body background-color=&amp;#39;#6693CF&amp;#39;&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;table width=&amp;#39;265&amp;#39; height=&amp;#39;135&amp;#39; cellpadding=&amp;#39;0&amp;#39; cellspacing=&amp;#39;0&amp;#39;&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tr align=&amp;#39;left&amp;#39; bgcolor=&amp;#39;#6693CF&amp;#39;&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td align=&amp;#39;left&amp;#39; colspan=&amp;#39;2&amp;#39;&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;font size=&amp;#39;2&amp;#39; color=&amp;#39;#FFFFFF&amp;#39;&amp;gt;&amp;lt;b&amp;gt;Please Enter Reject Reason&amp;lt;/font&amp;gt;&amp;lt;/b&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tr&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tr align=&amp;#39;left&amp;#39; bgcolor=&amp;#39;#E3EFFF&amp;#39;&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td align=&amp;#39;left&amp;#39;&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;font size=&amp;#39;2&amp;#39;&amp;gt;Reason:&amp;lt;/font&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td align=&amp;#39;left&amp;#39;&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;textarea cols=&amp;#39;25&amp;#39; rows=&amp;#39;4&amp;#39; id=&amp;#39;txtRejectReason&amp;#39; textmode=&amp;#39;multiline&amp;#39;&amp;gt;&amp;quot; + currentRejectComment&amp;nbsp; + &amp;quot;&amp;lt;/textarea&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tr&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tr width=&amp;#39;100%&amp;#39; align=&amp;#39;left&amp;#39; bgcolor=&amp;#39;#E3EFFF&amp;#39;&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td colspan=&amp;#39;2&amp;#39; align=&amp;#39;center&amp;#39;&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;button style=&amp;#39;width:50px&amp;#39;&amp;nbsp; id=&amp;#39;btnOk&amp;#39; title=&amp;#39;Ok&amp;#39; onclick=&amp;#39;BLOCKED SCRIPTwindow.opener.document.RejectAllWithReason(txtRejectReason.value);window.close();&amp;#39;&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Ok&amp;lt;/button&amp;gt;&amp;amp;nbsp;&amp;lt;button style=&amp;#39;width:50px&amp;#39; id=&amp;#39;btnCancel&amp;#39; title=&amp;#39;Cancel&amp;#39; onclick=&amp;#39;BLOCKED SCRIPTwindow.close();&amp;#39;&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Cancel&amp;lt;/button&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tr&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/table&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;htmlText += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;childWindow.document.write(htmlText);&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The HTML includes a text box for the cancel reason.&amp;nbsp; If you were to click cancel, it would simply give control back to the CRM Form.&amp;nbsp; If you click OK, it calls another function on the form to complete the rest of the save.&lt;/p&gt;
&lt;p&gt;On &amp;quot;OK&amp;quot; click, call this function which updates the cancel reason on the parent record along with the cancelled flag.&amp;nbsp; Update the cancel reason on all child records and deactivate the child records, all using JScript.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;document.RejectAllWithReason = function(rejectReason)&lt;br /&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;// OMITTED - updating child entity fields and deactivating in JScript&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Update parent&amp;nbsp;record fields and save&lt;br /&gt;&amp;nbsp; crmForm.all.inet_rejectcomment.DataValue = rejectReason+ &amp;quot; &amp;quot;;&lt;br /&gt;&amp;nbsp; crmForm.all.inet_rejectallflag.ForceSubmit = true;&lt;br /&gt;&amp;nbsp; crmForm.all.inet_rejectallflag.DataValue = true;&amp;nbsp; &lt;br /&gt;&amp;nbsp; crmForm.Save();&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;You now have a solution that works in the Offline Client and CRM Online without introducing complex deployment scenarios!&lt;/p&gt;
&lt;p&gt;Enjoy,&lt;br /&gt;Andrew&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.inetium.com/aggbug.aspx?PostID=28880" width="1" height="1"&gt;</description><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/CRM+4.0/default.aspx">CRM 4.0</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/CRM+Offline+Client/default.aspx">CRM Offline Client</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/JScript/default.aspx">JScript</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/CRM+Online/default.aspx">CRM Online</category></item><item><title>Account Hierarchies in CRM 4.0 - Part II</title><link>http://blogs.inetium.com/blogs/azimmer/archive/2009/12/03/account-hierarchies-in-crm-4-0-part-ii.aspx</link><pubDate>Thu, 03 Dec 2009 13:17:00 GMT</pubDate><guid isPermaLink="false">7346ef18-9fb1-4a4e-be41-9add5078176c:28876</guid><dc:creator>Andrew Zimmer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/rsscomments.aspx?PostID=28876</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/commentapi.aspx?PostID=28876</wfw:comment><comments>http://blogs.inetium.com/blogs/azimmer/archive/2009/12/03/account-hierarchies-in-crm-4-0-part-ii.aspx#comments</comments><description>&lt;p&gt;&lt;b&gt;UPDATE:&lt;/b&gt;&amp;nbsp; A new version of account hierarchies is included in the post &lt;a href="http://blogs.inetium.com/blogs/azimmer/archive/2010/01/21/silverlight-applications-in-crm-4-0.aspx"&gt;Silverlight Applications in CRM 4.0&lt;/a&gt; (&lt;a title="http://blogs.inetium.com/blogs/azimmer/archive/2010/01/21/silverlight-applications-in-crm-4-0.aspx" href="http://blogs.inetium.com/blogs/azimmer/archive/2010/01/21/silverlight-applications-in-crm-4-0.aspx"&gt;http://blogs.inetium.com/blogs/azimmer/archive/2010/01/21/silverlight-applications-in-crm-4-0.aspx&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In March I wrote a post on creating a hierarchical representation of an account within a custom web page.&amp;nbsp; Jeremy Winchell recently enhanced this functionality as a part of a &lt;a title="CRM Essentials" href="http://www.crmmn.com/default.aspx"&gt;CRM Essential&lt;/a&gt; session we held on Extending the Platform.&amp;nbsp; I wanted to show what he has done.&lt;/p&gt;
&lt;p&gt;Original Post: &lt;a title="http://blogs.inetium.com/blogs/azimmer/archive/2009/03/08/account-hierarchies-in-crm-4-0.aspx" href="http://blogs.inetium.com/blogs/azimmer/archive/2009/03/08/account-hierarchies-in-crm-4-0.aspx"&gt;http://blogs.inetium.com/blogs/azimmer/archive/2009/03/08/account-hierarchies-in-crm-4-0.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/accounthierarchypartII.gif"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/accounthierarchypartII.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;He made a couple of very useful enhancements.&amp;nbsp; The list now includes related contacts and opportunities along with any child accounts.&amp;nbsp; The CRM icons for opportunities, contact, and accounts are now displayed to easily identify the type of record.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re interested in having us build something like this for you, contact your account executive directly or email &lt;a title="sales@inetium.com" href="mailto:sales@inetium.com"&gt;sales@inetium.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;-Andrew&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.inetium.com/aggbug.aspx?PostID=28876" width="1" height="1"&gt;</description></item><item><title>Merging Records in Microsoft CRM</title><link>http://blogs.inetium.com/blogs/azimmer/archive/2009/10/10/merging-records-in-microsoft-crm.aspx</link><pubDate>Sat, 10 Oct 2009 23:13:00 GMT</pubDate><guid isPermaLink="false">7346ef18-9fb1-4a4e-be41-9add5078176c:28810</guid><dc:creator>Andrew Zimmer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/rsscomments.aspx?PostID=28810</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/commentapi.aspx?PostID=28810</wfw:comment><comments>http://blogs.inetium.com/blogs/azimmer/archive/2009/10/10/merging-records-in-microsoft-crm.aspx#comments</comments><description>&lt;p&gt;The SDK includes functionality to merge records.&amp;nbsp; When executing the merge it will deactivate the source record.&amp;nbsp; It will move any child records to the target record and it will overwrite any fields you specify on the actual target record.&lt;/p&gt;
&lt;p&gt;There are build-in merge classes for accounts, contacts and leads.&amp;nbsp; You can also merge any non-system entity using target merge dynamic:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TargetMergeLead&lt;/li&gt;
&lt;li&gt;TargetMergeAccount&lt;/li&gt;
&lt;li&gt;TargetMergeAccount&lt;/li&gt;
&lt;li&gt;TargetMergeDynamic&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Scenarios:&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;There are various scenarios when this logic can be put into use.&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Workflow &lt;/b&gt;- This functionality is especially useful when building out de-duplication logic.&amp;nbsp; I have seen it used within a workflow.&amp;nbsp; As records come in through a record import they are then merged with any duplicates.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Plugin &lt;/b&gt;- The same functionality can be build into a plugin.&amp;nbsp; Every time a record is created you can check for duplicates and merge.&amp;nbsp; &lt;/li&gt;
&lt;li&gt;&lt;b&gt;Entity Grid View Button &lt;/b&gt;- Add a button that will merge when two records are selected in the grid view.&amp;nbsp; This would be implemented in a custom ASP.Net web page.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Gotchas:&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;I have ran into a few gotchas when doing merges.&amp;nbsp; It requires you to manipulate some data before executing the merge.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Merging a lead and the target lead exists in a locked marketing list -  To fix this, unlock the marketing list, execute the merge, then re-lock the marketing list.&lt;/li&gt;
&lt;li&gt;Merging an account and the parent customer of the source account is the target account - To fix this, do not pass the parent customer field into the merge.&amp;nbsp; This case is not very likely to occur.&amp;nbsp; You may decide to allow for an error to be generated in this scenario.&lt;/li&gt;
&lt;li&gt;Merging an account and the parent customer of the target account is the source account - To fix this, blank out the parent customer field on the target before executing the merge.&amp;nbsp; This one is also one of those error that would be alright to throw, depending on your business rules.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;The Code&lt;/b&gt;:&lt;/p&gt;
&lt;p&gt;The code will take any field in the source record and overwrite the target record if the target record field is blank.&amp;nbsp; You can always override this.&amp;nbsp; I have a fields list that specifies fields that you always want to overwrite in the target record.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;While generating the update content on the account record it handles  gotchas 2 and 3.&lt;/p&gt;
&lt;p&gt;This code assumes that you have already retrieved the target record from CRM using a RetrieveMultipleRequest.&amp;nbsp; For example you could pull by StateCode of active, first name = @firstname, last name = @lastname, and emailaddress1 = @email.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public List&amp;lt;string&amp;gt; FieldsAlwaysOverwrite { get; set; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private void ProcessMerge(ICrmService service, DynamicEntity accountSource, DynamicEntity accountTarget, ref string notes)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Always overwrite account number and email address&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FieldsAlwaysOverwrite = new List&amp;lt;string&amp;gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FieldsAlwaysOverwrite.Add(&amp;quot;accountnumber&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FieldsAlwaysOverwrite.Add(&amp;quot;emailaddress1&amp;quot;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Create the target for the request.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TargetMergeAccount target = new TargetMergeAccount();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // EntityId is the GUID of the account that is being merged into.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; target.EntityId = (accountTarget.Properties[&amp;quot;accountid&amp;quot;] as Key).Value;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Create the request.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MergeRequest merge = new MergeRequest();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // SubordinateId is the GUID of the account merging.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; merge.SubordinateId = (accountSource.Properties[&amp;quot;accountid&amp;quot;] as Key).Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; merge.Target = target;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; merge.PerformParentingChecks = true;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Specify what contact to update on the actual accoutn record&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DynamicEntity updateContent = ExtractUpdateContent(service, accountSource, accountTarget, merge.SubordinateId, target.EntityId);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; merge.UpdateContent = updateContent;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Execute the request.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MergeResponse merged = (MergeResponse)service.Execute(merge);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private DynamicEntity ExtractUpdateContent(ICrmService service, DynamicEntity source,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DynamicEntity target, Guid sourceGuid, Guid targetGuid)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DynamicEntity updateContent = new DynamicEntity(&amp;quot;account&amp;quot;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (Property property in source.Properties)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Gotcha #2&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // If creating circular reference, don&amp;#39;t overwrite it&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (GetGuid(property) == targetGuid)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; continue;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Use source if target is blank&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!target.Properties.Contains(property.Name))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; updateContent.Properties.Add(property);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Use source if explicitly stated so&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (FieldsAlwaysOverwrite.Contains(property.Name.ToLower()))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; updateContent.Properties.Add(property);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Gotcha #3&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // If creating circular reference then null it out&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bool changedTarget = false;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (Property property in target.Properties)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (GetGuid(property) == sourceGuid)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (property is CustomerProperty)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Customer c = new Customer();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.IsNull = true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.IsNullSpecified = true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; target.Properties[property.Name] = c;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; changedTarget = true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (property is LookupProperty)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Lookup c = new Lookup();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.IsNull = true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.IsNullSpecified = true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; target.Properties[property.Name] = c;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; changedTarget = true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (changedTarget)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; service.Update(target);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return updateContent;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static Guid GetGuid(Property property)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (property is LookupProperty)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Lookup lookup = (property as LookupProperty).Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (lookup.IsNull == false &amp;amp;&amp;amp; lookup.IsNullSpecified == false)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return lookup.Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (property is CustomerProperty)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Customer lookup = (property as CustomerProperty).Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (lookup.IsNull == false &amp;amp;&amp;amp; lookup.IsNullSpecified == false)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return lookup.Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (property is KeyProperty)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Key lookup = (property as KeyProperty).Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return lookup.Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return Guid.Empty;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Handling Gotcha #1 - Lead is a Part of a Locked Marketing List&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;To handle merging a lead where the target lead is a part of a locked marketing list you should do the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Unlock the marketing list beforehand&lt;/li&gt;
&lt;li&gt;Execute the Merge&lt;/li&gt;
&lt;li&gt;Lock the marketing list&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Here is the Code:&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; private void ProcessMerge(ICrmService service, DynamicEntity leadSource, DynamicEntity leadTarget)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; BusinessEntityCollection lockedLists = GetLockedMarketingLists(service, CRMUtilities.GetGuid(leadSource, &amp;quot;leadid&amp;quot;).ToString(&amp;quot;B&amp;quot;));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (DynamicEntity entity in lockedLists.BusinessEntities)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; entity.Properties[&amp;quot;lockstatus&amp;quot;] = new CrmBoolean(false);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; service.Update(entity);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // Create the target for the request.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; TargetMergeLead target = new TargetMergeLead();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // EntityId is the GUID of the lead that is being merged into.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; target.EntityId = CRMUtilities.GetGuid(leadTarget, &amp;quot;leadid&amp;quot;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // Create the request.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; MergeRequest merge = new MergeRequest();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // SubordinateId is the GUID of the lead merging.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; merge.SubordinateId = CRMUtilities.GetGuid(leadSource, &amp;quot;leadid&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; merge.Target = target;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; merge.PerformParentingChecks = false;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; DynamicEntity updateContent = ExtractUpdateContent(leadSource, leadTarget);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; merge.UpdateContent = updateContent;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // Execute the request.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; MergeResponse merged = (MergeResponse)service.Execute(merge);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (DynamicEntity entity in lockedLists.BusinessEntities)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; entity.Properties[&amp;quot;lockstatus&amp;quot;] = new CrmBoolean(true);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; service.Update(entity);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; private BusinessEntityCollection GetLockedMarketingLists(ICrmService service, string leadId)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // Create the ColumnSet that indicates the properties to be retrieved.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ColumnSet cols = new ColumnSet();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // Set the properties of the ColumnSet.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; cols.Attributes.AddRange(new string[] { &amp;quot;lockstatus&amp;quot;, &amp;quot;listid&amp;quot; });&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // Create the FilterExpression.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; FilterExpression filter = new FilterBLOCKED EXPRESSION&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return key.Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return Guid.Empty;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.inetium.com/aggbug.aspx?PostID=28810" width="1" height="1"&gt;</description><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/CRM+4.0/default.aspx">CRM 4.0</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/Plugins/default.aspx">Plugins</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/SDK/default.aspx">SDK</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/Workflows/default.aspx">Workflows</category></item><item><title>Using Unresolved Email Recipients in CRM 4.0</title><link>http://blogs.inetium.com/blogs/azimmer/archive/2009/08/08/crm-4-0-using-unresolved-email-addresses.aspx</link><pubDate>Sat, 08 Aug 2009 20:48:00 GMT</pubDate><guid isPermaLink="false">7346ef18-9fb1-4a4e-be41-9add5078176c:28794</guid><dc:creator>Andrew Zimmer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/rsscomments.aspx?PostID=28794</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.inetium.com/blogs/azimmer/commentapi.aspx?PostID=28794</wfw:comment><comments>http://blogs.inetium.com/blogs/azimmer/archive/2009/08/08/crm-4-0-using-unresolved-email-addresses.aspx#comments</comments><description>&lt;p&gt;Unresolved emails are useful in that you can send an email to someone without having them setup as a system record (contact, account, lead, queue, user, ect).&amp;nbsp; Unresolved email addresses are turned off by default.&amp;nbsp; They should be used with caution.&amp;nbsp; If you send an email to an unresolved address it will not track the email to that lead/contact since one does not exist.&amp;nbsp; It also does not leverage the email &amp;quot;Do not allow&amp;quot; flags to allow people to opt out of emails.&amp;nbsp; With those considerations, there are still cases where it is very useful to&amp;nbsp;send an email to someone without having to create a contact record.&lt;/p&gt;
&lt;p&gt;I will show two example of sending emails to unresolved recipients.&amp;nbsp; The first&amp;nbsp;will be sent from the email form using JavaScript.&amp;nbsp; The second will be done in a plugin.&amp;nbsp; We will add two unresolved email addresses as CC addresses on emails sent from&amp;nbsp;a contact record.&lt;/p&gt;
&lt;p&gt;Before we begin.&amp;nbsp; You must flip the setting to allow unresolved recipients.&amp;nbsp; Go to Settings --&amp;gt; Administration --&amp;gt; System Settings --&amp;gt; Email Tab.&amp;nbsp; Set Allow messages with unresolved e-mail recipients to be sent to yes.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/UnresolvedEmailJScript1.gif"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/UnresolvedEmailJScript1.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Second, we will add a couple of fields to the contact for secondary contacts email addresses.&amp;nbsp; These fields will contain our unresolved email addresses.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/UnresolvedEmailJScript2.gif"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/UnresolvedEmailJScript2.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;b&gt;JavaScript Implementation&lt;br /&gt;&lt;/b&gt;When the user clicks &amp;quot;Send Email&amp;quot; from the contact form we want the CC field to default with the two unresolved email addresses.&amp;nbsp; To do this we add the following Jscript to the onload of the email form.&amp;nbsp; The code will check to see if the regarding object is of type contact since this form is used for all emails.&amp;nbsp; Then it adds each email address to an email object that follows the activityparty schema for unresolved email addresses.&amp;nbsp; It has a type of 9206 and the email is set in the data property.&lt;br /&gt;&lt;br /&gt;if (crmForm.FormType == 1 &amp;amp;&amp;amp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; crmForm.all.regardingobjectid.DataValue != null &amp;amp;&amp;amp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; crmForm.all.regardingobjectid.DataValue[0].typename == &amp;quot;contact&amp;quot; &amp;amp;&amp;amp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; window.opener != null &amp;amp;&amp;amp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; window.opener.document != null) {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var ar = new Array();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var emailObj = new Object();&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (window.opener.document.crmForm.all.new_secondarycontactemail1 != null &amp;amp;&amp;amp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; window.opener.document.crmForm.all.new_secondarycontactemail1.DataValue != null) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; emailObj = new Object();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; emailObj[&amp;#39;type&amp;#39;] = &amp;#39;9206&amp;#39;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; emailObj[&amp;#39;category&amp;#39;] = &amp;#39;3&amp;#39;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; emailObj[&amp;#39;data&amp;#39;] = window.opener.document.crmForm.all.new_secondarycontactemail1.DataValue;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; emailObj[&amp;#39;name&amp;#39;] = window.opener.document.crmForm.all.new_secondarycontactemail1.DataValue;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ar.push(emailObj);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (window.opener.document.crmForm.all.new_secondarycontactemail2 != null &amp;amp;&amp;amp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; window.opener.document.crmForm.all.new_secondarycontactemail2.DataValue != null) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; emailObj = new Object();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; emailObj[&amp;#39;type&amp;#39;] = &amp;#39;9206&amp;#39;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; emailObj[&amp;#39;category&amp;#39;] = &amp;#39;3&amp;#39;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; emailObj[&amp;#39;data&amp;#39;] = window.opener.document.crmForm.all.new_secondarycontactemail2.DataValue;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; emailObj[&amp;#39;name&amp;#39;] = window.opener.document.crmForm.all.new_secondarycontactemail2.DataValue;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ar.push(emailObj);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; crmForm.all.cc.DataValue = ar;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Lastly, publish the customization.&amp;nbsp; When you click &amp;quot;Send Email&amp;quot; from the contact form your addresses will be added to the CC.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/UnresolvedEmailJScript3.gif"&gt;&lt;img src="http://blogs.inetium.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/UnresolvedEmailJScript3.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Plugin Implementation&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The same functionality can be added using a plugin.&amp;nbsp; The benefits of using a plugin versus a client side implementation is that you can implement consistent functionality regardless of whether the email send is triggered from a client portal, another plugin, or through the CRM UI.&amp;nbsp; The JavaScript implemenation is useful in that the user can see who the email is being sent to before they click Send.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Install the plugin using the registration tool as a pre-create step for email save.&amp;nbsp; This will add the CC on the initial save of the email.&amp;nbsp; It is triggered regardless of whether the user clicks save or send from the email form.&amp;nbsp; The code also includes duplicate checking logic. So, if the user adds the email address to the CC from the form it will not duplicate the same address in the plugin.&lt;/p&gt;
&lt;p&gt;using System.Web;&lt;br /&gt;using System.Net;&lt;/p&gt;
&lt;p&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;using Microsoft.Crm.Sdk;&lt;br /&gt;using Microsoft.Crm.SdkTypeProxy;&lt;br /&gt;using Microsoft.Crm.Sdk.Query;&lt;br /&gt;using System.Reflection;&lt;br /&gt;using System.Web.Services.Protocols;&lt;br /&gt;using Microsoft.Crm.SdkTypeProxy.Metadata;&lt;br /&gt;using Microsoft.Crm.Sdk.Metadata;&lt;br /&gt;using Inetium.CrmPlugins;&lt;br /&gt;using System.Collections;&lt;/p&gt;
&lt;p&gt;namespace Inetium.CrmPlugins.Plugins&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class&amp;nbsp;CaseUnresolvedEmailPlugin : IPlugin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Execute(IPluginExecutionContext context)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ICrmService service = null;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (context.InputParameters.Properties.Contains(&amp;quot;Target&amp;quot;) &amp;amp;&amp;amp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.InputParameters.Properties[&amp;quot;Target&amp;quot;] is DynamicEntity)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DynamicEntity entityInput = context.InputParameters.Properties[&amp;quot;Target&amp;quot;] as DynamicEntity;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (entityInput.Properties.Contains(&amp;quot;regardingobjectid&amp;quot;))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Lookup regardingObjectLookup = entityInput.Properties[&amp;quot;regardingobjectid&amp;quot;] as Lookup;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; service = context.CreateCrmService(true);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Only using this for contacts&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (regardingObjectLookup.type == EntityName.contact.ToString())&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Pull parent contact - using helper&amp;nbsp;method&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DynamicEntity ctn = CRMUtilities.RetrieveById(service, EntityName.contact.ToString(), &amp;quot;contactid&amp;quot;, regardingObjectLookup.Value, new ColumnSet(new string[]{&amp;quot;new_secondarycontactemail1&amp;quot;, &amp;quot;new_secondarycontactemail2&amp;quot;}));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!ctn.Properties.Contains(&amp;quot;new_secondarycontactemail1&amp;quot;) &amp;amp;&amp;amp; !ctn.Properties.Contains(&amp;quot;new_secondarycontactemail2&amp;quot;))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string email1 = ctn.Properties.Contains(&amp;quot;new_secondarycontactemail1&amp;quot;) ? ctn.Properties[&amp;quot;new_secondarycontactemail1&amp;quot;].ToString() : &amp;quot;&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string email2 = ctn.Properties.Contains(&amp;quot;new_secondarycontactemail2&amp;quot;) ? ctn.Properties[&amp;quot;new_secondarycontactemail2&amp;quot;].ToString() : &amp;quot;&amp;quot;;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DynamicEntity[] partyArrayExisting = entityInput.Properties.Contains(&amp;quot;cc&amp;quot;) ? entityInput.Properties[&amp;quot;cc&amp;quot;] as DynamicEntity[] : new DynamicEntity[] { };&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;DynamicEntity&amp;gt; partyList = new List&amp;lt;DynamicEntity&amp;gt;(partyArrayExisting);&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (email1 != &amp;quot;&amp;quot; &amp;amp;&amp;amp; !IsEmailAlreadyInCC(email1, partyList))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DynamicEntity party = new DynamicEntity();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; party.Name = EntityName.activityparty.ToString();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; party.Properties[&amp;quot;addressused&amp;quot;] = email1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; partyList.Add(party);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (email2 != &amp;quot;&amp;quot; &amp;amp;&amp;amp; !IsEmailAlreadyInCC(email2, partyList))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DynamicEntity party = new DynamicEntity();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; party.Name = EntityName.activityparty.ToString();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; party.Properties[&amp;quot;addressused&amp;quot;] = email2;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; partyList.Add(party);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Generate CC&amp;#39;s list by adding in those from contacts&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (partyList.Count &amp;gt; 0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; entityInput.Properties[&amp;quot;cc&amp;quot;] = partyList.ToArray();&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch (SoapException se)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new Exception(se.Detail.InnerText);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch (Exception ex)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new Exception(ex.Message);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; finally&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (service != null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; service.Dispose();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; service = null;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private bool IsEmailAlreadyInCC(string email, List&amp;lt;DynamicEntity&amp;gt; activityPartyList)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bool bAlreadyExists = false;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (DynamicEntity existingParty in activityPartyList)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // compare to existing CCs&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (existingParty.Properties.Contains(&amp;quot;addressused&amp;quot;) &amp;amp;&amp;amp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (existingParty.Properties[&amp;quot;addressused&amp;quot;].ToString() == email))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bAlreadyExists = true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return bAlreadyExists;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.inetium.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/azimmer/RegardingInfo3.gif"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.inetium.com/aggbug.aspx?PostID=28794" width="1" height="1"&gt;</description><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/CRM+4.0/default.aspx">CRM 4.0</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/Plugins/default.aspx">Plugins</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/unresolved+recipient/default.aspx">unresolved recipient</category><category domain="http://blogs.inetium.com/blogs/azimmer/archive/tags/email/default.aspx">email</category></item></channel></rss>