<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2291594830244924527</id><updated>2012-03-01T13:27:07.054-08:00</updated><category term='SOAP'/><category term='Ribbon'/><category term='Debugging'/><category term='Sandbox'/><category term='CRM'/><category term='Silverlight'/><category term='Plug-Ins'/><category term='Testing'/><title type='text'>Erik Pool</title><subtitle type='html'>XRM Development, etc.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://erikpool.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://erikpool.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Erik Pool</name><uri>http://www.blogger.com/profile/07240189216754286258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>11</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2291594830244924527.post-3123673326619751183</id><published>2011-10-21T17:34:00.000-07:00</published><updated>2011-10-21T17:34:47.664-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ribbon'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM'/><title type='text'>New CRM 2011 Ribbon Editing Tool</title><content type='html'>Phew! So it's Friday night and for the past week I've been between jobs (i.e, unemployed), so I've finally had the time to create a tool that I've been wanting to build for a while.&amp;nbsp; So here is a new tool for customizing ribbons on Microsoft Dynamics CRM 2011.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;It's different from other ribbon editors available because it shows a full real-time preview of what the ribbon will look like in CRM, and it should eliminate the need to spend hours studying the ribbon XML schema in the CRM SDK before trying to add a new button to a ribbon. No more scrolling through pages of XML looking for the ID of the element you want to insert your button into. Just click "New Button", position it where you want, then define the actions and enable rules or display rules. Then click "Save" to save the changes back to CRM.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-HYR5QxNnK9U/TqIPLH_18JI/AAAAAAAAAC4/yKsw8PiEQ80/s1600/EditButton.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-HYR5QxNnK9U/TqIPLH_18JI/AAAAAAAAAC4/yKsw8PiEQ80/s1600/EditButton.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I'll post more about this project later, but for now you can find it at &lt;a href="http://crmvisualribbonedit.codeplex.com/"&gt;http://crmvisualribbonedit.codeplex.com/ &lt;/a&gt;&lt;br /&gt;It's currently in a beta state and still need alot of testing, but please check it out!&lt;br /&gt;&lt;br /&gt;-Erik Pool&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2291594830244924527-3123673326619751183?l=erikpool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erikpool.blogspot.com/feeds/3123673326619751183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erikpool.blogspot.com/2011/10/new-crm-2011-ribbon-editing-tool.html#comment-form' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/3123673326619751183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/3123673326619751183'/><link rel='alternate' type='text/html' href='http://erikpool.blogspot.com/2011/10/new-crm-2011-ribbon-editing-tool.html' title='New CRM 2011 Ribbon Editing Tool'/><author><name>Erik Pool</name><uri>http://www.blogger.com/profile/07240189216754286258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-HYR5QxNnK9U/TqIPLH_18JI/AAAAAAAAAC4/yKsw8PiEQ80/s72-c/EditButton.png' height='72' width='72'/><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2291594830244924527.post-5694690027054664243</id><published>2011-10-14T17:10:00.000-07:00</published><updated>2011-10-14T17:17:02.569-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ribbon'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM'/><title type='text'>Understanding CRM Ribbon XML - Part 3: Group Templates</title><content type='html'>&lt;div class="MsoNormal"&gt;&lt;span style="color: #134f5c; font-size: large;"&gt;&lt;span style="color: black; font-size: small;"&gt;This is part 3 in a series of posts on customizing CRM ribbons:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #134f5c; font-size: large;"&gt;&lt;span style="color: black; font-size: small;"&gt;- &lt;a href="http://erikpool.blogspot.com/2011/10/understanding-crm-ribbon-xml-part-1.html"&gt;Part 1: Understanding the content and structure of the ribbon xml&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://erikpool.blogspot.com/2011/10/understanding-crm-ribbon-xml-part-2.html"&gt;Part 2: Customizing ribbons by editing the RibbonDiffXml&lt;/a&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #134f5c; font-size: large;"&gt;&lt;span style="color: black; font-size: small;"&gt;- Part 3: Understanding Group Templates (this post)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #134f5c; font-size: large;"&gt;&lt;b&gt;How do Templates work?&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;Until now I’ve completely skipped over the templates section of the ribbon xml. This is because Templates can be the most difficult part of ribbon customizations to understand. Templates are used to determine how groups of controls on a ribbon are arranged. The template used will determine the order of the buttons, as well as the size of the buttons. And the template will also determine how the group shrinks when there isn’t enough room on the page for the full ribbon.&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 12.0pt;"&gt;For most scenarios (such as adding a button to an existing group) you won’t even need to worry about templates, you can just add the button set it's TemplateAlias attribute to “isv” and you’re done. However, if you are creating a new Group (or a new tab), then it’s worth knowing how Templates work.&lt;/div&gt;First, take a look at the buttons in the UI section. Notice how they each have a TemplateAlias attribute:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-uk3fLZK0mDg/TpjK0p_fP5I/AAAAAAAAAB4/uioQOMpi02o/s1600/10+-+Button+Xml+with+TemplateAlias.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-uk3fLZK0mDg/TpjK0p_fP5I/AAAAAAAAAB4/uioQOMpi02o/s1600/10+-+Button+Xml+with+TemplateAlias.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Also notice how each Group has a Template Attribute:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-MaZEAco2CAM/TpjLDXchYAI/AAAAAAAAACA/5Nc2UABds_c/s1600/11+-+Group+XML+with+Template.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-MaZEAco2CAM/TpjLDXchYAI/AAAAAAAAACA/5Nc2UABds_c/s1600/11+-+Group+XML+with+Template.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;If we scroll down to the Templates section, we will find the Template that the group is using. Each Template will have multiple Layouts inside it with names like “LargeMedium”, or “LargeSmall”. One of these Layouts will be used to determine the arrangement of the controls inside the Group (we’ll see how CRM actually decides which layout to use in a bit).&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-sXOMmCI0Keo/TpjLLJEEAzI/AAAAAAAAACI/hyxd52iouko/s1600/12+-+Flexible2+Template.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-sXOMmCI0Keo/TpjLLJEEAzI/AAAAAAAAACI/hyxd52iouko/s1600/12+-+Flexible2+Template.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Inside of each layout, there are two ways that the arrangement of buttons and controls can be defined... &lt;br /&gt;&lt;b&gt;&lt;br /&gt;1. Layout using OverflowSections&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The most common way is using &lt;b&gt;OverflowSections&lt;/b&gt;. Each OverflowSection will be arranged in the ribbon group horizontally from left to right, and will contain all the buttons from the group that have the specified TemplateAlias.&amp;nbsp; This image shows the "Collaborate" group, which is using the "LargeMedium" layout of the "Flexible2" template:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-aLCRf4h0-4A/TpjLcRBYD6I/AAAAAAAAACQ/eWp73DbxAkg/s1600/13+-+Collaborate+Group+showing+Overflow+Sections.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-aLCRf4h0-4A/TpjLcRBYD6I/AAAAAAAAACQ/eWp73DbxAkg/s1600/13+-+Collaborate+Group+showing+Overflow+Sections.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;In the image above, all of the buttons using the "&lt;b&gt;o1&lt;/b&gt;"&lt;b&gt; &lt;/b&gt;templateAlias are placed &lt;b&gt;&lt;i&gt;before&lt;/i&gt; &lt;/b&gt;all of the buttons with the "&lt;b&gt;o2&lt;/b&gt;"&lt;b&gt; &lt;/b&gt;TemplateAlias, regardless of their sequence number.&amp;nbsp; But controls with the same TemplateAlias will be ordered inside the OverflowSection based on their sequence number. In this example there are no buttons currently using the “&lt;b&gt;isv&lt;/b&gt;” TemplateAlias, so the isv OverflowSection is not shown at all.    &lt;br /&gt;An overflowSection with a Type of “OneRow” will have just a single row of buttons, while a Type of “ThreeRow” will have three rows of buttons stacked on top of eachother.&amp;nbsp; The DisplayMode determines what size the buttons in the OverflowSection will be. There are three sizes - Large, Medium, and Small:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-2Djtoq2YAQ4/TpjLy653ItI/AAAAAAAAACY/8qKcb2pRnA8/s1600/14+-+OverflowSection+Rows+and+Sizes.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="260" src="http://4.bp.blogspot.com/-2Djtoq2YAQ4/TpjLy653ItI/AAAAAAAAACY/8qKcb2pRnA8/s400/14+-+OverflowSection+Rows+and+Sizes.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Notice that all of the default templates each have an OverflowSection for the “isv” templateAlias. This is so developers can easily just add a new button to any group without having to worry about templates or layouts. If you just always use the “isv” TemplateAlias then the button will show up at the end of the group.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2. Layout using Sections and Rows&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;The other way that Layouts can be defined is using Sections and Rows. Sections and Rows allow the template to have much more precision than OverflowSections when defining the arrangement of controls. Each control in the Group is placed into a specific Section and Row. For example, the Activities group on the “Add Existing” tab uses Sections and Rows to get a very specific arrangement of controls:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-pWynXEcn4rk/TpjL_bHVI9I/AAAAAAAAACg/pybU2ZS3GrE/s1600/15+-+Activities+Template+-+Sections+and+Rows.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-pWynXEcn4rk/TpjL_bHVI9I/AAAAAAAAACg/pybU2ZS3GrE/s1600/15+-+Activities+Template+-+Sections+and+Rows.png" /&gt;&amp;nbsp;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;Notice that even with the sections and rows in this Layout there are still two OverflowSections at the end of the layout for the "o1" and "isv" TemplateAliases. The Sections and Rows offer more exact control over layout but the OverflowSections off flexibility if you need to add additional custom controls to this group.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;&lt;b&gt;Tip:&lt;/b&gt; Any time you see a control with a TemplateAlias that starts with “c”, it is using Sections and Rows for layout. Any time the TemplateAlias starts with “o”, it is using OverflowSections (c = ConfrolRef, o = overflowSection). &lt;/i&gt;&lt;/blockquote&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: #134f5c; font-size: large;"&gt;How does CRM decide which layout to use?&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Each template has multiple layouts, and each of these layouts defines how the ribbon group will look at different sizes. This is where the Scaling section comes into play. If you look at the scaling section of a Tab (way back up in the UI section of the xml file), you will see that it maps Groups to Layouts:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-16oryxwnyVE/TpjNGNNkDUI/AAAAAAAAACo/jOaHlx4D8oo/s1600/16+-+Scale+xml.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-16oryxwnyVE/TpjNGNNkDUI/AAAAAAAAACo/jOaHlx4D8oo/s1600/16+-+Scale+xml.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The MaxSize element defines which layout the group will use when the ribbon is at its full size. If the user shrinks the window size (reducing the amount of horizontal space available for the ribbon), then it will switch to the next Scale listed. &lt;br /&gt;&lt;br /&gt;For each Tab, all of the MaxSize and Scale elements for every groups in a tab are all collected together in one single Scaling element, but if we look at only the Scales for the “Collaborate” group (ignoring all the scales for the other groups), we can see how scales change the layout of the group as horizontal size of the ribbon is decreased:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-1hCK-SDnqWg/TpjNj63hM7I/AAAAAAAAACw/wt_LcXPHViQ/s1600/17++-+Scaling+Diagram.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-1hCK-SDnqWg/TpjNj63hM7I/AAAAAAAAACw/wt_LcXPHViQ/s1600/17++-+Scaling+Diagram.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;When the Ribbon is full-width, it uses the first MaxSize scale, which points to the “&lt;i&gt;LargeMedium”&lt;/i&gt; layout. As the available width shrinks, it moves to the next Scale in the list, which uses the “&lt;i&gt;LargeSmall”&lt;/i&gt; layout. Finally, as the width of the ribbon shrinks further, it reaches the 3&lt;sup&gt;rd&lt;/sup&gt; and final Scale, which uses the “&lt;i&gt;Popup”&lt;/i&gt; layout. If you open CRM and navigate to Accounts, you can see how the size of the “collaborate” group changes as you adjust the size of the browser window.&lt;br /&gt;&lt;br /&gt;The last Layout in a template is usually a special “&lt;b&gt;Popup&lt;/b&gt;” layout. The Popup layout tells CRM which layout to use when the group is shrunk down to its smallest size and becomes a popup menu. The LayoutTitle attribute in the element refers to another layout that is used to arrange the content of the popup (in this case, the popup uses the LargeMedium layout).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: #134f5c; font-size: large;"&gt;How to use this information?&lt;/span&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;So how do we use this information about templates and scales? Well, if you just need to add a button to an existing group it doesn’t really matter. You can just set button’s TemplateAlias to “isv” and you’re done. However, if you are creating a completely new group for the ribbon then you will need to pick a Template and define the MaxSize and Scaling elements for the group. And if none of the default Templates will work for you, then you can even define your own template in the RibbonDiffXml.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To create a new Group, you will need to do the following:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Add a new Group element to the Tab’s “Groups” collection using a CustomAction.&lt;/li&gt;&lt;li&gt;Add a new MaxSize element into the Tab’s “Scaling” collection using a CustomAction.&lt;/li&gt;&lt;li&gt;Optionally, add additional scales to the scaling collection (it is a good idea to at least add a “Popup” scale).&lt;/li&gt;&lt;li&gt;If you want to specify EnableRules or DisplayRules for the Group, then you will need to create a CommandDefinition for the group, otherwise you can just set the group’s command attribute to “Mscrm.Enabled” (this will make the group always enabled).&lt;/li&gt;&lt;li&gt;Add a new LocLabel to the LocLabels section for the groups Title attribute.&lt;/li&gt;&lt;li&gt;If you defined a Popup scale for the group, then the group should have the Image32by32Popup attribute defined (this is the image shown when the group turns into a popup button at the smallest scale).  &lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;div style="color: #134f5c;"&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;In Conclusion...&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The arrangement of controls in a ribbon Group is defined by which Template the group is using, and by which TemplateAlias the controls are using.&lt;/li&gt;&lt;li&gt;Template layouts can be defined using either OverflowSections or Sections and Rows.&lt;/li&gt;&lt;li&gt;The layout that CRM uses for a group depends on the MaxSize and Scaling elements defined in the Tab, and also the size of the browser window.&lt;/li&gt;&lt;li&gt;When adding a button to an existing group, you should just use the “isv” TemplateAlias, but when creating new groups you will need to select a Template and define the group’s scaling.&lt;/li&gt;&lt;/ol&gt;By the way, these posts are meant to supplement the &lt;a href="http://msdn.microsoft.com/en-us/library/gg309639.aspx"&gt;SDK&lt;/a&gt;, not replace it, but if there's any part of these posts that you found difficult or confusing please let me know in the comments)&lt;br /&gt;&lt;br /&gt;thanks,&lt;br /&gt;~Erik Pool&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2291594830244924527-5694690027054664243?l=erikpool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erikpool.blogspot.com/feeds/5694690027054664243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erikpool.blogspot.com/2011/10/understanding-crm-ribbon-xml-part-3.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/5694690027054664243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/5694690027054664243'/><link rel='alternate' type='text/html' href='http://erikpool.blogspot.com/2011/10/understanding-crm-ribbon-xml-part-3.html' title='Understanding CRM Ribbon XML - Part 3: Group Templates'/><author><name>Erik Pool</name><uri>http://www.blogger.com/profile/07240189216754286258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-uk3fLZK0mDg/TpjK0p_fP5I/AAAAAAAAAB4/uioQOMpi02o/s72-c/10+-+Button+Xml+with+TemplateAlias.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2291594830244924527.post-556512043845082080</id><published>2011-10-05T17:14:00.000-07:00</published><updated>2011-10-05T17:14:04.603-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ribbon'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM'/><title type='text'>Understanding CRM Ribbon XML - Part 2: updating the ribbon</title><content type='html'>This is part 2 in a series of posts about the CRM 2011 Ribbon:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://erikpool.blogspot.com/2011/10/understanding-crm-ribbon-xml-part-1.html"&gt;Part 1 - Content and Structure of the Ribbon.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Part 2 - Editing the ribbon (this post)&lt;/li&gt;&lt;li&gt;Part 3 - How Ribbon Templates work (coming soon)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: #0b5394; font-size: large;"&gt;How to edit a ribbon&lt;/span&gt;&lt;/b&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;&lt;br /&gt;You edit a ribbon by updating the RibbonDiffXml section of the Customizations.xml file. This file is part of the CRM solution zip file that is exported from CRM. Basically, you must create a new solution in CRM that contains the entity who’s ribbon you want to edit. Then you must export the solution and extract the customizations xml file from the exported zip file. See &lt;a href="http://msdn.microsoft.com/en-us/library/gg327952.aspx"&gt;&lt;span style="color: blue;"&gt;this page&lt;/span&gt;&lt;/a&gt; for more information on how to export and import ribbons.&lt;br /&gt;&lt;br /&gt;Now remember, the CRM solution only contains the changes to the ribbon, so when you view the RibbonDiffXml for a solution exported from CRM, you will not see the full definition of the ribbon. In fact, if no changes to the ribbon have been made yet, it will be almost empty:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://2.bp.blogspot.com/-8-8bvCIk0KE/TozvNlVV7yI/AAAAAAAAABo/qIlG7JzDWfo/s1600/06+-+Blank+RibbonDiffxml.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://2.bp.blogspot.com/-8-8bvCIk0KE/TozvNlVV7yI/AAAAAAAAABo/qIlG7JzDWfo/s640/06+-+Blank+RibbonDiffxml.png" width="631" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;One thing that is important to realize is that the different sections of the ribbon are edited differently. To add a new &lt;b&gt;CommandDefinition&lt;/b&gt;, &lt;b&gt;EnableRule&lt;/b&gt;, or &lt;b&gt;DisplayRule&lt;/b&gt;, you can simply insert the new item into the appropriate section inside the RibbonDiffXml:&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://4.bp.blogspot.com/-kZj5CT8BOsc/TozvY4UG3yI/AAAAAAAAABs/BW819Y5WUlU/s1600/07+-+CommandDef+and+Rules+in+DiffXml.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-kZj5CT8BOsc/TozvY4UG3yI/AAAAAAAAABs/BW819Y5WUlU/s1600/07+-+CommandDef+and+Rules+in+DiffXml.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;span style="color: #0b5394; font-size: large;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0b5394; font-size: large;"&gt;&lt;b&gt;&lt;o:p&gt;CustomActions&lt;/o:p&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;However, to change anything in the &lt;b&gt;UI&lt;/b&gt; section, you need to create &lt;b&gt;CustomActions&lt;/b&gt;. Each CustomAction tells CRM to make a change to the UI section of the ribbon. A customAction could tell CRM to insert a new button into the ribbon UI. Or a CustomAction could tell CRM to remove an existing button from the UI. Essentially, each CustomAction either defines a block of XML that should be inserted into the UI section of the ribbon, or indicates which element of the XML should be removed from the ribbon. &lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;&lt;br /&gt;Take a look at this example: &lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://4.bp.blogspot.com/-ELtp6oeeCRs/TozvkzB4YiI/AAAAAAAAABw/-69h7mk203M/s1600/08+-+CustomAction+xml.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-ELtp6oeeCRs/TozvkzB4YiI/AAAAAAAAABw/-69h7mk203M/s1600/08+-+CustomAction+xml.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This CustomAction tells CRM to insert the XML inside the &lt;b&gt;&lt;i&gt;CommandUIDefinition&lt;/i&gt; &lt;/b&gt;element into the XML element defined by the Location attribute (highlighted in &lt;span style="background-color: yellow;"&gt;yellow&lt;/span&gt;). In this case the CustomAction is inserting a new Button element into the Mscrm.HomepageGrid.account.MainTab.Collaborate.Controls element. &lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;&lt;br /&gt;Notice that the Location attribute has “_children” at the end of it. This is just a convention used by CRM, it means “insert the xml content into the children of the specified element”. &lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;&lt;br /&gt;This is what the base ribbon xml looks like after CRM has used the CustomAction to insert the button into the “Mscrm.HomepageGrid.account.MainTab.Collaborate.Controls” element:&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://3.bp.blogspot.com/-I-ZiD5hsYqg/Tozv-j0esLI/AAAAAAAAAB0/qEghCQfk7vA/s1600/09+-+UI+after+applying+customAction.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="389" src="http://3.bp.blogspot.com/-I-ZiD5hsYqg/Tozv-j0esLI/AAAAAAAAAB0/qEghCQfk7vA/s640/09+-+UI+after+applying+customAction.png" width="792" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0b5394; font-size: large;"&gt;&lt;b&gt;Removing Existing Buttons and Controls &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you want to &lt;b&gt;remove an existing element from a ribbon&lt;/b&gt;, you can use &lt;b&gt;HideCustomAction&lt;/b&gt;. With HideCustomAction, you just specify which element inside the ribbon UI to hide. For example, the following will hide the ExportData button on the account homepage ribbon:&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0pt;"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: small;"&gt;HideCustomAction&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: small;"&gt; &lt;/span&gt;&lt;span style="color: red; font-family: Consolas; font-size: small;"&gt;Location&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: small;"&gt;=&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: small;"&gt;"&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% yellow; color: blue; font-family: Consolas; font-size: small;"&gt;Mscrm.HomepageGrid.quote.MainTab.ExportData&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: small;"&gt;"&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="color: red; font-family: Consolas; font-size: small;"&gt;&lt;span style="color: black; font-family: Times New Roman;"&gt; &lt;/span&gt;HideActionId&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: small;"&gt;=&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: small;"&gt;"&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: small;"&gt;Sample.HomepageGrid.quote.MainTab.ExportData.HideAction&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: small;"&gt;" &lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: small;"&gt;/&amp;gt;&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;&lt;br /&gt;Remember,&amp;nbsp;each solution only defines the actions used to change the base ribbon xml. So you could have one CRM solution that adds a ribbon button, and then another Solution layered on top of it that hides the same button.&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;&lt;br /&gt;&lt;b style="color: #0b5394;"&gt;&lt;span style="font-size: large;"&gt;A quick note about LocLabels&lt;/span&gt;&lt;/b&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0pt;"&gt;In the RibbonDiffXml from your solution, you will see a RibbonDiffXml section that doesn’t appear in the Base ribbon XML from the resources\exportedribbonxml. This is where you store the localized labels, tooltips, and descriptions for your custom ribbon buttons. Labels are defined in the LocLabels section of the RibbonDiffXml and are referenced by the controls using the “$LocLabels:” syntax:&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0pt; word-break: break-all;"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 8pt;"&gt;Button&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 8pt;"&gt; &lt;/span&gt;&lt;span style="color: red; font-family: Consolas; font-size: 8pt;"&gt;Id&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;=&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 8pt;"&gt;"&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;Sample.account.grid.SendToOtherSystem.Button&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 8pt;"&gt;"&lt;/span&gt;&lt;/div&gt;&lt;div style="margin: 0in 0in 0pt 0.5in; word-break: break-all;"&gt;&lt;span style="color: red; font-family: Consolas; font-size: 8pt;"&gt;Command&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;=&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 8pt;"&gt;"&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;Sample.account.grid.SendToOtherSystem.Command&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 8pt;"&gt;"&lt;/span&gt;&lt;/div&gt;&lt;div style="margin: 0in 0in 0pt 0.5in; word-break: break-all;"&gt;&lt;span style="color: red; font-family: Consolas; font-size: 8pt;"&gt;LabelText&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% yellow; color: blue; font-family: Consolas; font-size: 8pt;"&gt;=&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% yellow; color: black; font-family: Consolas; font-size: 8pt;"&gt;"&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% yellow; color: blue; font-family: Consolas; font-size: 8pt;"&gt;$LocLabels:Sample.account.SendToOtherSystem.LabelText&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 8pt;"&gt;"&lt;/span&gt;&lt;/div&gt;&lt;div style="margin: 0in 0in 0pt 0.5in; word-break: break-all;"&gt;&lt;span style="color: red; font-family: Consolas; font-size: 8pt;"&gt;TemplateAlias&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;=&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 8pt;"&gt;"&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;o1&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 8pt;"&gt;"&lt;/span&gt;&lt;/div&gt;&lt;div style="margin: 0in 0in 0pt 0.5in; word-break: break-all;"&gt;&lt;span style="color: red; font-family: Consolas; font-size: 8pt;"&gt;Image32by32&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;=&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 8pt;"&gt;"&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;$webresource:sample_/icons/TIcon32x32.png&lt;/span&gt;&lt;span style="color: black; font-family: Consolas; font-size: 8pt;"&gt;" &lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;/&amp;gt;&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0pt;"&gt;Why don’t LocLabels appear in the base ribbon xml? I suspect it’s because none of the built-in CRM buttons actually use LocLabels, instead they use their own localized resources embedded in the CRM application.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0pt;"&gt;&lt;b&gt;&lt;span style="color: #0b5394;"&gt;&lt;span style="font-size: large;"&gt;To recap:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;The ribbon XML definition cannot be edited directly, instead you must edit the RibbonDiffXml from the solution customizations.xml file.&lt;o:p&gt;&lt;/o:p&gt; &lt;br /&gt;&lt;/li&gt;&lt;li&gt;New CommandDefinitions, EnableRules, and DisplayRules can be added directly to the available sections in the RibbonDiffXml.&lt;o:p&gt;&lt;/o:p&gt; &lt;br /&gt;&lt;/li&gt;&lt;li&gt;New UI elements (i.e, new buttons, groups, or tabs) must be added to the ribbon using CustomActions&lt;o:p&gt;&lt;/o:p&gt; &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Existing tabs, groups, and buttons can be hidden using HideCustomActions.&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;In the next post I will discuss how the CRM Ribbon uses Templates to determine positioning and size of ribbon controls.&lt;o:p&gt;&lt;/o:p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2291594830244924527-556512043845082080?l=erikpool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erikpool.blogspot.com/feeds/556512043845082080/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erikpool.blogspot.com/2011/10/understanding-crm-ribbon-xml-part-2.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/556512043845082080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/556512043845082080'/><link rel='alternate' type='text/html' href='http://erikpool.blogspot.com/2011/10/understanding-crm-ribbon-xml-part-2.html' title='Understanding CRM Ribbon XML - Part 2: updating the ribbon'/><author><name>Erik Pool</name><uri>http://www.blogger.com/profile/07240189216754286258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-8-8bvCIk0KE/TozvNlVV7yI/AAAAAAAAABo/qIlG7JzDWfo/s72-c/06+-+Blank+RibbonDiffxml.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2291594830244924527.post-5170480354256539890</id><published>2011-10-01T16:47:00.000-07:00</published><updated>2011-10-06T10:23:12.006-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ribbon'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM'/><title type='text'>Understanding CRM Ribbon XML - Part 1: ribbon content and structure</title><content type='html'>&lt;div style="color: #134f5c;"&gt;This is part 1 in a series of posts about the CRM 2011 Ribbon:&lt;a href="http://erikpool.blogspot.com/2011/10/understanding-crm-ribbon-xml-part-1.html"&gt;&lt;br /&gt;&amp;nbsp;- Part 1 - Content and Structure of the Ribbon. (this post)&lt;/a&gt;&lt;a href="http://erikpool.blogspot.com/2011/10/understanding-crm-ribbon-xml-part-2.html"&gt;&lt;br /&gt;&amp;nbsp;- Part 2 - Editing the ribbon.&lt;/a&gt;&lt;br /&gt;&amp;nbsp;- Part 3 - How Ribbon Templates work (coming soon)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Demystifying the CRM 2011 ribbon xml&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;The CRM 2011 &lt;a href="http://msdn.microsoft.com/en-us/library/gg309408.aspx"&gt;SDK&lt;/a&gt; provides a number of &lt;a href="http://msdn.microsoft.com/en-us/library/gg334532.aspx"&gt;walkthroughs&lt;/a&gt; on adding buttons and tabs to the CRM entity ribbons, but they don’t really offer an in-depth explanation of why each step is necessary, or what other options are available. In the next few posts I will attempt to explain fully how the ribbons for CRM 2011 can be customized, and explain in more detail some of the areas that the SDK only touches lightly. In this first post I will cover the basic structure and content of the ribbon XML, and in following posts we'll go over editing the ribbon and how ribbon templates work.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;div style="color: #134f5c;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #134f5c;"&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Your CRM solution doesn’t contain the entire ribbon&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;The first thing you &lt;b&gt;&lt;i&gt;must&lt;/i&gt; &lt;/b&gt;know about CRM ribbons, is that a CRM solution will not contain the entire definition of a ribbon. The CRM database &lt;i&gt;does&lt;/i&gt; contain a base ribbon definition for each entity, but this definition is not directly customizable. When you modify the ribbon, your CRM solution will only store the &lt;i&gt;changes&lt;/i&gt; made to the ribbon. This way multiple solutions can each make changes to the same ribbon and they will all get layered on top of each other, without any solutions overwriting each other.&lt;br /&gt;&lt;br /&gt;So when making changes to any CRM ribbon you have to keep in mind that you’re not actually editing the ribbon XML definition, you are editing an XML file (ribbondiffxml) that describes the &lt;i&gt;changes&lt;/i&gt; made to the ribbon.&lt;br /&gt;&lt;div style="color: #134f5c;"&gt;&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: #134f5c;"&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Viewing the Full Ribbon Definition&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;Each ribbon in CRM is defined by an xml file, and the first thing you should do when trying to understand how ribbon customization works is to look at the full ribbon xml for a CRM entity. There are two ways you can get the ribbon xml for an entity:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Look in the resources\exportedribbonxml folder in the CRM SDK. This folder contains the ribbon xml for all the system entities in CRM.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Or, you can export the ribbon xml for a specific entity programmatically, using the &lt;a href="http://msdn.microsoft.com/en-us/library/gg334699.aspx"&gt;RetrieveEntityRibbonRequest&lt;/a&gt; message. For uncustomized system entities this will give you the same xml that is found in resources\exportedribbonxml.&lt;/li&gt;&lt;/ol&gt;Both of these methods will give you the &lt;b&gt;full &lt;/b&gt;ribbon definition from CRM (not just the customizations you’ve added to the ribbon).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #134f5c; font-size: large;"&gt;&lt;b&gt;Contents of the Ribbon XML&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As you look through the ribbon xml you will see four main sections: &lt;i&gt;UI&lt;/i&gt;,&lt;i&gt; Templates&lt;/i&gt;, &lt;i&gt;CommandDefinitons&lt;/i&gt;, and &lt;i&gt;RuleDefinitions&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://3.bp.blogspot.com/-Q7SOTmClKUU/ToeefapiXOI/AAAAAAAAABQ/wnqd9W7imlQ/s1600/01+-+FourSections.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-Q7SOTmClKUU/ToeefapiXOI/AAAAAAAAABQ/wnqd9W7imlQ/s1600/01+-+FourSections.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="clear: both;"&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;UI &lt;/b&gt;–&lt;b&gt; &lt;/b&gt;The UI section contains all the Tabs, Groups, and buttons that show up in the ribbon. This defines what you actually &lt;i&gt;see&lt;/i&gt; in the ribbon.&lt;b&gt; &lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Templates&lt;/b&gt; – Templates define the layout of ribbon groups. The size of buttons and controls on a ribbon, how they are arranged, and how they collapse when the window size shrinks all depends on what templates the ribbon is using.&lt;b&gt; &lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;CommandDefinitons&lt;/b&gt; – CommandDefinitions define what the ribbon buttons &lt;i&gt;do&lt;/i&gt; (i.e., what actions are executed when a user clicks the button).&lt;b&gt; &lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;RuleDefinitions&lt;/b&gt; – RuleDefinitions define when a button is displayed and when it is enabled or disabled.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="color: #134f5c; font-size: large;"&gt;&lt;b&gt;UI Section&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #134f5c;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Take a look at the xml inside the UI section and you will see a hierarchy of Tabs, which contain Groups, which then contain Controls (including ribbon buttons). Each of these elements corresponds to a part of the ribbon:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://3.bp.blogspot.com/-gHS2IB2epLs/ToefVwYH4MI/AAAAAAAAABU/qc0DY7b4-eI/s1600/02+-+UI+Diagram.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-gHS2IB2epLs/ToefVwYH4MI/AAAAAAAAABU/qc0DY7b4-eI/s1600/02+-+UI+Diagram.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;For the most part, the UI section is pretty straightforward, but there are a few things worth pointing out:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Notice that there are several different types of tabs: &lt;i&gt;HomepageGrid&lt;/i&gt;, &lt;i&gt;Form&lt;/i&gt;, and &lt;i&gt;SubGrid&lt;/i&gt;. These tabs will be difference parts of the CRM application. Read about the different types of tabs &lt;a href="http://msdn.microsoft.com/en-us/library/gg309420.aspx"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Each button has a sequence number and a TemplateAlias. These are used to derermine the ordering of the buttons and the size of the button. We’ll look at how templates work in the next post.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Inside each tab, in addition to a collection of Groups you will see a “Scaling” section. Ignore this section for now, we’ll get to it in a bit (essentially, it defines how the groups behave when there isn’t enough room on the screen to display the full ribbon).&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="color: #134f5c; font-size: large;"&gt;&lt;b&gt;&lt;br /&gt;Command Definitions&lt;/b&gt;&lt;/span&gt;&lt;span style="color: #134f5c;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Look at the Buttons in the UI section:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://4.bp.blogspot.com/-VeRV-Qr4paQ/ToefoSUDnYI/AAAAAAAAABY/ZeE-3jd85Ls/s1600/03+-+Button+xml.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-VeRV-Qr4paQ/ToefoSUDnYI/AAAAAAAAABY/ZeE-3jd85Ls/s1600/03+-+Button+xml.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Notice that the buttons each have a “Command” attribute. If we search the XML file for the command, we see that it’s a reference to a &lt;b&gt;CommandDefinition&lt;/b&gt; (which is found in the commandDefinitions section, of course):&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://3.bp.blogspot.com/-pvyoHXtkiR0/ToefyP2Q-sI/AAAAAAAAABc/8LVtm96vpZs/s1600/04+-+CommandDefinition+xml.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-pvyoHXtkiR0/ToefyP2Q-sI/AAAAAAAAABc/8LVtm96vpZs/s1600/04+-+CommandDefinition+xml.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;You can see that in the CommandDefinition, there is an &lt;b&gt;Action&lt;/b&gt;, and also a number of &lt;b&gt;DisplayRules&lt;/b&gt; and &lt;b&gt;EnableRules&lt;/b&gt;. The Action defines what happens when the button is pressed. The Action can be either a Javascript function or a URL. In the example shown above, the action calls the “openObj” JavaScript function. See &lt;a href="http://msdn.microsoft.com/en-us/library/gg328199.aspx"&gt;this page&lt;/a&gt; for more information on how to define ribbon actions.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #134f5c; font-size: large;"&gt;&lt;b&gt;RuleDefinitions&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The EnableRules and DisplayRules in the CommandDefinition define which rules are used to determine when the button is enabled or visible. The rules you see inside the CommandDefinition are just pointers, the actual definitions of these rules are defined in the &lt;b&gt;RuleDefinitions&lt;/b&gt; section:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://3.bp.blogspot.com/-Fcxi0GKdqKA/ToeuviAGG-I/AAAAAAAAABk/Pzc7_FZyzk8/s1600/05+-+RuleDefinitions.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-Fcxi0GKdqKA/ToeuviAGG-I/AAAAAAAAABk/Pzc7_FZyzk8/s1600/05+-+RuleDefinitions.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;There are many different kinds of rules that can be used within each EnableRule or DisplayRule, allowing you to create complex conditions for almost any kind of scenario. In the example shown above, the CreateSelectedEntityPermission rule uses an EntityPrivilegeRule to make sure that the “New Record” button is only enabled when the current user has the Create permission on the selected entity. To understand the full capability of EnableRules and DisplayRules, check out the following SDK articles: &lt;a href="http://msdn.microsoft.com/en-us/library/gg334682.aspx"&gt;EnableRules&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/gg328560.aspx"&gt;DisplayRules&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #134f5c;"&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;In Conclusion..&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;To recap, we have the &lt;b&gt;UI&lt;/b&gt; section, which defines the actual visual elements that make up a ribbon. The buttons in the UI section link to a &lt;b&gt;CommandDefinition&lt;/b&gt;, which defines what the button &lt;i&gt;does&lt;/i&gt;. And the CommandDefinition links to multiple&lt;b&gt; RuleDefinitions&lt;/b&gt;, which define when the button is visible or enabled. What about the Templates section? We will get to that in a future post.&lt;br /&gt;&lt;br /&gt;In the &lt;a href="http://erikpool.blogspot.com/2011/10/understanding-crm-ribbon-xml-part-2.html"&gt;next post&lt;/a&gt;, we'll see how to actually &lt;i&gt;edit &lt;/i&gt;the ribbon.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2291594830244924527-5170480354256539890?l=erikpool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erikpool.blogspot.com/feeds/5170480354256539890/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erikpool.blogspot.com/2011/10/understanding-crm-ribbon-xml-part-1.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/5170480354256539890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/5170480354256539890'/><link rel='alternate' type='text/html' href='http://erikpool.blogspot.com/2011/10/understanding-crm-ribbon-xml-part-1.html' title='Understanding CRM Ribbon XML - Part 1: ribbon content and structure'/><author><name>Erik Pool</name><uri>http://www.blogger.com/profile/07240189216754286258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-Q7SOTmClKUU/ToeefapiXOI/AAAAAAAAABQ/wnqd9W7imlQ/s72-c/01+-+FourSections.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2291594830244924527.post-9214896242622000895</id><published>2011-08-28T11:29:00.000-07:00</published><updated>2011-08-28T11:39:26.660-07:00</updated><title type='text'>Error Logging Plug-in exceptions in CRM Online</title><content type='html'>(Cross-posted from the &lt;a href="http://www.avanadeblog.com/xrm/2011/08/error-logging-plug-in-exceptions-in-crm-online.html"&gt;Avanade Xrm Blog&lt;/a&gt;, where I've been posting more recently)&lt;br /&gt;&lt;br /&gt;For a while now we've been trying to find some way of logging plug-in exceptions on CRM Online (and I've also seen a number of &lt;a href="http://social.microsoft.com/Forums/en-US/crmdevelopment/thread/3bbe3cc0-e2a7-461d-87a2-f150b1698bb4" target="_self"&gt;posts&lt;/a&gt; on the CRM Developer forums asking if this is possible).&lt;br /&gt;&lt;br /&gt;Logging exceptions that originate from CRM plug-ins presents a number  of problems, especially in CRM online.&amp;nbsp; First of all, plug-ins in CRM  online are sand-boxed, so you do not have access to the file system or  event log.&amp;nbsp; The CRM SDK offers a tracing service that can be used, but  this only displays tracing information to the end user.&amp;nbsp; No permanent  log of the exception is recorded.&lt;br /&gt;&amp;nbsp; &lt;br /&gt;The logical solution is to just write all exception messages to a custom CRM entity (The SDK even &lt;a href="http://msdn.microsoft.com/en-us/library/gg328574.aspx#loggingandtracing" target="_self"&gt;mentions this idea&lt;/a&gt;).&amp;nbsp;  But this is also problematic because synchronous plug-ins are run  inside of a database transaction. So if your plug-in runs into an  exception the transaction will get rolled back, including rolling back  the creation of any Error Log record you created while handling the  exception.&lt;br /&gt;&lt;br /&gt;Ideally, we want all of the operations of the plug-in to be inside  the database transaction, but the creation of the errorlog record to &lt;i&gt;NOT &lt;/i&gt;be  part of the transaction (so that any changes made by the plug-in are  rolled back, but an admin can still read the error message afterwards).  This can be achieved in an on-premise CRM installation by just creating a  new OrganizationService proxy from scratch, instead of using the one  provided by the plugin context. But again, this doesn't work in CRM  Online because of the sandbox restrictions (when running in partial  trust you cannot make WCF calls or use the libraries included in the CRM  SDK for connecting to CRM online).&lt;br /&gt;&lt;br /&gt;Fortunately, there is a different way to connect to CRM online while in partial-trust, and the answer comes from &lt;a href="http://www.dynamicslight.com/2010/04/mscrm-development-tips-tricks-3-connecting-to-mscrm-online/" target="_self" title="mscrm development tips and tricks - connecting to mscrm online"&gt;this post&lt;/a&gt; on Dimaz Pramudya's blog.&lt;br /&gt;&lt;blockquote&gt;&lt;div style="color: #990000;"&gt;&lt;i&gt;"There is a sample on how to achieve  this using Passport authentication in MSCRM SDK. ... it failed  miserably in  shared hosting environment which runs Medium or High trust  level.&lt;br /&gt;&lt;br /&gt;What I wanted to share today is an  alternative way to get the Windows Live Id ticket that works virtually  on any environment.&amp;nbsp; This method uses the RPS (Relying Party Suites)  authentication option for Windows Live."&lt;/i&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;/blockquote&gt;This post is over a year old, and only describes connecting to the  CRM 4.0 webservicce, but it will still work with CRM 2011 online.&lt;br /&gt;&lt;br /&gt;Dimaz has created two c# classes; &lt;i&gt;LiveIdTicketAcquirer &lt;/i&gt;and &lt;i&gt;CrmOnlineQueryManager&lt;/i&gt;,  which together can be used to connect to CRM online from within a CRM  plug-in.&amp;nbsp; And this new connection will not be part of the database  transaction, which means it can be used to write our error log messages  back to a CRM entity.&lt;br /&gt;&lt;br /&gt;In the following code sample I am using the CrmOnlineQueryManager to log an exception to a custom entity called "new_error":&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 9pt;"&gt;public&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 9pt;"&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;TestPlugin&lt;/span&gt; : &lt;span style="color: #2b91af;"&gt;IPlugin&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Execute(&lt;span style="color: #2b91af;"&gt;IServiceProvider&lt;/span&gt; serviceProvider)&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; &lt;span style="color: blue;"&gt;try&lt;/span&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;throw&lt;/span&gt; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Exception&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"Testing Error logging"&lt;/span&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; &lt;span style="color: blue;"&gt;catch&lt;/span&gt;( &lt;span style="color: #2b91af;"&gt;Exception&lt;/span&gt; ex)&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; &lt;span style="color: #2b91af;"&gt;CrmOnlineErrorLogger&lt;/span&gt;.LogError(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;span style="color: blue;"&gt;throw&lt;/span&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; }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 9pt;"&gt;class&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 9pt;"&gt; &lt;span style="color: #2b91af;"&gt;CrmOnlineErrorLogger&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;const&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; username = &lt;span style="color: #a31515;"&gt;"myLiveId"&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;const&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; password = &lt;span style="color: #a31515;"&gt;"myPassword"&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;const&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; organization = &lt;span style="color: #a31515;"&gt;"myOrgName"&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;span style="font-family: Consolas; font-size: 9pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; LogError(&lt;span style="color: #2b91af;"&gt;Exception&lt;/span&gt; ex)&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;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;CrmOnlineQueryManager&lt;/span&gt; queryManager = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;CrmOnlineQueryManager&lt;/span&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; &lt;span style="color: blue;"&gt;var&lt;/span&gt; crmService = queryManager.Connect(username, password, organization);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;span style="font-family: Consolas; font-size: 9pt;"&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; &lt;span style="color: #2b91af;"&gt;DynamicEntity&lt;/span&gt; entity = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;DynamicEntity&lt;/span&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; entity.Name = &lt;span style="color: #a31515;"&gt;"new_error"&lt;/span&gt;; &lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;span style="font-family: Consolas; font-size: 9pt;"&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; &lt;span style="color: #2b91af;"&gt;StringProperty&lt;/span&gt; exceptionType = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;StringProperty&lt;/span&gt;() { Name = &lt;span style="color: #a31515;"&gt;"new_exceptiontype"&lt;/span&gt;, Value = ex.GetType().FullName };&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;span style="font-family: Consolas; font-size: 9pt;"&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; &lt;span style="color: #2b91af;"&gt;StringProperty&lt;/span&gt; details = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;StringProperty&lt;/span&gt;() { Name = &lt;span style="color: #a31515;"&gt;"new_details"&lt;/span&gt;, Value = ex.Message + &lt;span style="color: #a31515;"&gt;": "&lt;/span&gt; + ex.StackTrace };&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;span style="font-family: Consolas; font-size: 9pt;"&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; entity.Properties = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Property&lt;/span&gt;[] { exceptionType, details };&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;span style="font-family: Consolas; font-size: 9pt;"&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; crmService.Create(entity);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&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; }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;br /&gt;&lt;/div&gt;When I run this plug-in, the thrown exception rolls back the update I was making, and I see the expected error message:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://2.bp.blogspot.com/-f5hme6QLtUg/TlqE7LAXdTI/AAAAAAAAABI/YTaVGRBbrT8/s1600/ErrorLogging1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="469" src="http://2.bp.blogspot.com/-f5hme6QLtUg/TlqE7LAXdTI/AAAAAAAAABI/YTaVGRBbrT8/s640/ErrorLogging1.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;But I also see a log of the exception in my custom "Errors" table:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://2.bp.blogspot.com/-5tpjLh2uf8c/TlqFQIsscPI/AAAAAAAAABM/zikcps9CqTA/s1600/ErrorLogging2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="408" src="http://2.bp.blogspot.com/-5tpjLh2uf8c/TlqFQIsscPI/AAAAAAAAABM/zikcps9CqTA/s640/ErrorLogging2.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;So now we can do error logging on CRM Online.&amp;nbsp; Of course, this is  just a proof of concept. There's a few more steps we would need to take  before using this in a production environment..&lt;br /&gt;&lt;ol&gt;&lt;li&gt;This code still connects to the old CRM 4.0 webservice. Presumably a  similar connector could be made that uses the 2011 endpoint. &lt;br /&gt;&lt;/li&gt;&lt;li&gt;There may be performance issues.&amp;nbsp; I've noticed its a bit slow to log  errors, but a lot of the slowdown can be reduced by trimming the crm4  webservice proxy class down to just the minimum components needed.&amp;nbsp;  Also, the slowdown only occurs when the plug-in actually throws an  error, which may be acceptable.&amp;nbsp; Bottom line, this technique still needs  to be fully tested.&lt;/li&gt;&lt;/ol&gt;The source-code for this proof-of-concept can be found &lt;a href="https://docs.google.com/viewer?a=v&amp;amp;pid=explorer&amp;amp;chrome=true&amp;amp;srcid=0BzDptMVvkXuwMjk4MWU0ZTAtNWExNS00MzU0LWFmNTItMThjMzFlZWU4ZTQz&amp;amp;hl=en_US"&gt;here&lt;/a&gt;. (this code is provided "as is" and provides no warranties or guarantees).&lt;br /&gt;&lt;br /&gt;~Erik Pool&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2291594830244924527-9214896242622000895?l=erikpool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erikpool.blogspot.com/feeds/9214896242622000895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erikpool.blogspot.com/2011/08/error-logging-plug-in-exceptions-in-crm.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/9214896242622000895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/9214896242622000895'/><link rel='alternate' type='text/html' href='http://erikpool.blogspot.com/2011/08/error-logging-plug-in-exceptions-in-crm.html' title='Error Logging Plug-in exceptions in CRM Online'/><author><name>Erik Pool</name><uri>http://www.blogger.com/profile/07240189216754286258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-f5hme6QLtUg/TlqE7LAXdTI/AAAAAAAAABI/YTaVGRBbrT8/s72-c/ErrorLogging1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2291594830244924527.post-3963064358260543940</id><published>2011-03-20T15:10:00.000-07:00</published><updated>2011-04-20T11:05:53.188-07:00</updated><title type='text'>Filtering generated entities with CrmSvcUtil</title><content type='html'>In CRM 2011 you can create early-bound entity classes using the &lt;a href="http://msdn.microsoft.com/en-us/library/gg327844.aspx"&gt;code generation utility&lt;/a&gt; (CrmSvcUtil.exe) that comes with the SDK.&amp;nbsp; This gives you nice strongly-typed entity classes that you can use with full intellisense in Visual Studio and in linq queries (and many other benefits).&lt;br /&gt;&lt;br /&gt;However, the cs file generated from this utility can be over 5 - 10MB in size, which is a lot when you want to include it in a CRM plug-in where you should try to keep your assembly as small as possible.&lt;br /&gt;&lt;br /&gt;By default the utility will generate classes for every entity in the CRM organization, but fortunately Microsoft has provided a way to filter which entities are generated. &lt;br /&gt;&lt;br /&gt;To filter the entities that are generate, we need to create an extension for the CrmSvcUtil utility. Basically, we have to create a small class library that implements an interface used by the utility. The SDK provides a &lt;a href="http://msdn.microsoft.com/en-us/library/gg327844.aspx#bkmk_extensions"&gt;little bit of info&lt;/a&gt;, but not much in the way of examples.&amp;nbsp; So here's what we need to do:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Create a new C# class library project in Visual Studio called SvcUtilFilter.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;In the project, add references to the following:&lt;/li&gt;&lt;ol&gt;&lt;li&gt;CrmSvcUtil.exe&amp;nbsp;&amp;nbsp; This exe has the interface we will implement.&lt;/li&gt;&lt;li&gt;Microsoft.Xrm.Sdk.dll&amp;nbsp; (found in the CRM SDK).&lt;/li&gt;&lt;li&gt;System.Runtime.Serialization.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;&amp;nbsp; Add the following class to the project: &lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;using&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt; System;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;using&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt; System.Collections.Generic;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;using&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt; System.Xml.Linq;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;using&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt; Microsoft.Crm.Services.Utility;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;using&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt; Microsoft.Xrm.Sdk.Metadata;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;namespace&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt; SvcUtilFilter&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: grey;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: grey;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: grey;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; CodeWriterFilter for CrmSvcUtil that reads list of entities from an xml file to &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: grey;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; determine whether or not the entity class should be generated.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: grey;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: grey;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;CodeWriterFilter&lt;/span&gt; : &lt;span style="color: #2b91af;"&gt;ICodeWriterFilterService&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//list of entity names to generate classes for.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;HashSet&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;&amp;gt; _validEntities = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;HashSet&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//reference to the default service.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ICodeWriterFilterService&lt;/span&gt; _defaultService = &lt;span style="color: blue;"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: grey;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: grey;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: grey;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; constructor&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: grey;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: grey;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: grey;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: grey;"&gt;&amp;lt;param name="defaultService"&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;default implementation&lt;/span&gt;&lt;span style="color: grey;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; CodeWriterFilter( &lt;span style="color: #2b91af;"&gt;ICodeWriterFilterService&lt;/span&gt; defaultService )&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;._defaultService = defaultService;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LoadFilterData();&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: grey;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: grey;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: grey;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; loads the entity filter data from the filter.xml file&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: grey;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: grey;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; LoadFilterData()&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;XElement&lt;/span&gt; xml = &lt;span style="color: #2b91af;"&gt;XElement&lt;/span&gt;.Load(&lt;span style="color: #a31515;"&gt;"filter.xml"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;XElement&lt;/span&gt; entitiesElement = xml.Element(&lt;span style="color: #a31515;"&gt;"entities"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af;"&gt;XElement&lt;/span&gt; entityElement &lt;span style="color: blue;"&gt;in&lt;/span&gt; entitiesElement.Elements(&lt;span style="color: #a31515;"&gt;"entity"&lt;/span&gt;))&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&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; _validEntities.Add(entityElement.Value.ToLowerInvariant());&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: grey;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: grey;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: grey;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; /Use filter entity list to determine if the entity class should be generated.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: grey;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: grey;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; GenerateEntity(&lt;span style="color: #2b91af;"&gt;EntityMetadata&lt;/span&gt; entityMetadata, &lt;span style="color: #2b91af;"&gt;IServiceProvider&lt;/span&gt; services)&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; (_validEntities.Contains(entityMetadata.LogicalName.ToLowerInvariant()));&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//All other methods just use default implementation:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; GenerateAttribute(&lt;span style="color: #2b91af;"&gt;AttributeMetadata&lt;/span&gt; attributeMetadata, &lt;span style="color: #2b91af;"&gt;IServiceProvider&lt;/span&gt; services)&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; _defaultService.GenerateAttribute(attributeMetadata, services);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; GenerateOption(&lt;span style="color: #2b91af;"&gt;OptionMetadata&lt;/span&gt; optionMetadata, &lt;span style="color: #2b91af;"&gt;IServiceProvider&lt;/span&gt; services)&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; _defaultService.GenerateOption(optionMetadata, services);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; GenerateOptionSet(&lt;span style="color: #2b91af;"&gt;OptionSetMetadataBase&lt;/span&gt; optionSetMetadata, &lt;span style="color: #2b91af;"&gt;IServiceProvider&lt;/span&gt; services)&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; _defaultService.GenerateOptionSet(optionSetMetadata, services);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; GenerateRelationship(&lt;span style="color: #2b91af;"&gt;RelationshipMetadataBase&lt;/span&gt; relationshipMetadata, &lt;span style="color: #2b91af;"&gt;EntityMetadata&lt;/span&gt; otherEntityMetadata, &lt;span style="color: #2b91af;"&gt;IServiceProvider&lt;/span&gt; services)&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; _defaultService.GenerateRelationship(relationshipMetadata, otherEntityMetadata, services);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; GenerateServiceContext(&lt;span style="color: #2b91af;"&gt;IServiceProvider&lt;/span&gt; services)&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; _defaultService.GenerateServiceContext(services);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;ol&gt;&lt;/ol&gt;&lt;br /&gt;This class implements the ICodeWriterFilterService interface.&amp;nbsp; This interface is used by the class generation utility to determine which entities, attrributes, etc. should actually be generated.&amp;nbsp; The interface is very simple and just has seven methods that are passed metadata info and return a boolean indicating whether or not the metadata should be included in the generated code file. &amp;nbsp; &lt;br /&gt;&lt;br /&gt;For now I just want to be able to determine which entities are generated, so in the constructor I read from an XML file (filter.xml) that holds the list of entities to generate and put the list in a Hashset.&amp;nbsp; The format of the xml is this:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 8pt;"&gt;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 8pt;"&gt;filter&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 8pt;"&gt;entities&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 8pt;"&gt;entity&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;systemuser&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;entity&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 8pt;"&gt;entity&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;team&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;entity&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 8pt;"&gt;entity&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;role&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;entity&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 8pt;"&gt;entity&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;businessunit&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;entity&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 8pt;"&gt;entities&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: 8pt;"&gt;filter&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;Take a look at the methods in the class. In the GenerateEntity method, we can simply check the EntityMetadata parameter against our list of valid entities and return true if it's an entity that we want to generate.&lt;br /&gt;&lt;br /&gt;For all of the other methods we want to just do whatever the default implementation of the utility is.&amp;nbsp; Notice how the constructor of the class accepts a defaultService parameter.&amp;nbsp; We can just save a reference to this default service and use it whenever we want to stick with the default behavior.&amp;nbsp; All of the other methods in the class just call the default service.&lt;br /&gt;&lt;br /&gt;To use our extension when running the utility, we just have to make sure the compiled DLL and the filter.xml file are in the same folder as CrmSvcUtil.exe, and set the /codewriterfilter command-line argument when running the utility (as described in the &lt;a href="http://msdn.microsoft.com/en-us/library/gg327844.aspx#bkmk_extensions"&gt;SDK&lt;/a&gt;):&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;crmsvcutil.exe /url:http://&lt;span style="color: #999999;"&gt;&amp;lt;server&amp;gt;&lt;span style="color: black;"&gt;/&lt;/span&gt;&amp;lt;org&amp;gt;&lt;/span&gt;/XrmServices/2011/Organization.svc /out:sdk.cs&amp;nbsp; /namespace:&lt;span style="color: #999999;"&gt;&amp;lt;namespace&amp;gt;&lt;/span&gt; &lt;span style="color: red;"&gt;/codewriterfilter:SvcUtilFilter.CodeWriterFilter,SvcUtilFilter&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;That's it! You now have a generated sdk.cs file that is only a few hundred kilobytes instead of 5MB. &lt;br /&gt;&lt;br /&gt;One final note:&amp;nbsp; There is actually a lot more you can do with extensions to the code generation utility.&amp;nbsp; For example: if you return true in the GenerateOptionSet method, it will actually generated Enums for each CRM picklist (which it doesn't normally do by default).&lt;br /&gt;&lt;br /&gt;Also, the source code for this SvcUtilFilter example can be found &lt;a href="https://docs.google.com/leaf?id=0BzDptMVvkXuwZWJiMzkwNDgtZjA2OS00ODA0LWFiNWUtMmVjZjVlYTY4Zjhk&amp;amp;hl=en"&gt;here&lt;/a&gt;.&amp;nbsp; Use at your own risk, no warranties, etc. etc. &lt;br /&gt;&lt;br /&gt;-Erik Pool&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2291594830244924527-3963064358260543940?l=erikpool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erikpool.blogspot.com/feeds/3963064358260543940/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erikpool.blogspot.com/2011/03/filtering-generated-entities-with.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/3963064358260543940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/3963064358260543940'/><link rel='alternate' type='text/html' href='http://erikpool.blogspot.com/2011/03/filtering-generated-entities-with.html' title='Filtering generated entities with CrmSvcUtil'/><author><name>Erik Pool</name><uri>http://www.blogger.com/profile/07240189216754286258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2291594830244924527.post-6226297666172269924</id><published>2011-03-01T21:25:00.000-08:00</published><updated>2011-03-01T22:53:43.420-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SOAP'/><category scheme='http://www.blogger.com/atom/ns#' term='Debugging'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM'/><title type='text'>Debugging Silverlight web-resources that connect to CRM Online.</title><content type='html'>Debugging Silverlight web-resources in CRM 2011 can be pretty tedious  when you have to constantly re-upload your XAP file to the CRM server  and then manually attach the debugger to the IE process. If you run the  Silverlight application from your own development machine (using the  ASP.NET Development server) you can quickly start debugging by hitting  F5 in Visual Studio, but the app won't be able to make any requests to  the CRM server because of Silverlight's cross-domain restrictions.&lt;br /&gt;&lt;br /&gt;If  you have an on-premise CRM server you can get around the cross-domain  restrictions by putting a &lt;a href="http://msdn.microsoft.com/en-us/library/cc197955%28v=vs.95%29.aspx"&gt;ClientAccessPolicy.xml&lt;/a&gt; file in the root of the  CRM web application (&lt;a href="http://mkonrad.blogspot.com/2011/02/crm-2011-debuggin-silverlight.html"&gt;See Markus Konrad's post on creating the policy file&lt;/a&gt;), but CRM online won't let you upload a  ClientAccessPolicy, so you have to be a little more clever.&amp;nbsp; One method  is to just create a proxy to pass all the requests to the CRM server.&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #990000;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;Creating a proxy for CRM SOAP requests&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;span style="color: #666666;"&gt;&lt;span style="color: #444444;"&gt;&lt;i&gt;A quick note&lt;/i&gt;: This works for the &lt;a href="http://msdn.microsoft.com/en-us/library/gg594452.aspx"&gt;SOAP Organization service&lt;/a&gt; and the  example at the end of this post only uses the SOAP service. I'm not sure  if a similar proxy would work for the &lt;a href="http://msdn.microsoft.com/en-us/library/gg334279.aspx"&gt;REST&lt;/a&gt; endpoint&amp;nbsp; (Given the REST  endpoint's limitation I rarely use it anyway). &lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;To get web-service requests to go from a Silverlight application w just need a few things:&lt;br /&gt;1. Create an aspx page in the web project that's hosting the Silverlight app that will act as our proxy.&lt;br /&gt;2. Program the proxy page to forward all posted requests to the CRM Online web-service endpoint.&lt;br /&gt;3. Authenticate against CRM Online and attach the LiveId security token to each request.&lt;br /&gt;4. Configure the Silverlight app to point to the proxy page.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Steps  1 and 2 are actually pretty straightforward once you pull out fiddler  and figure out what the soap requests work like. Step 3 is the  complicated bit but the sample code in the CRM SDK provides an example  of authenticating against CRM Online (see  sdk\samplecode\cs\wsdlbasedproxies\online). Once you've authenticated and have the security token you can just inject the token right into the header of the SOAP request.&lt;br /&gt;&lt;br /&gt;I've built an example application which you can download &lt;a href="https://docs.google.com/leaf?id=0BzDptMVvkXuwMWFlZTg5MzgtMTgxNi00NWYxLWI1MmUtYTk4OGYxZmNhZjhm&amp;amp;hl=en"&gt;here&lt;/a&gt;.&amp;nbsp; It's just a simple Silverlight application that makes create, retrieve, update, delete, and execute request to CRM Online using the proxy described above.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://i.imgur.com/mVgQv.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="321" src="http://i.imgur.com/mVgQv.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To try it out just update the constants defined at the top of Proxy.aspx.cs:&lt;br /&gt;&lt;blockquote&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: green; font-family: Consolas; font-size: 9.5pt;"&gt;//Update these constants to match your CRM Online account&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;&lt;span style="color: blue;"&gt;const&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; host = &lt;span style="color: #a31515;"&gt;"orgName.api.crm.dynamics.com"&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;&lt;span style="color: blue;"&gt;const&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; userName = &lt;span style="color: #a31515;"&gt;"erik.pool@example.com"&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;&lt;span style="color: blue;"&gt;const&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; password = &lt;span style="color: #a31515;"&gt;"Password"&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;Also note the &lt;i&gt;GetOrganizationService &lt;/i&gt;method in the Silverlight app. If the current page is running on "localhost" it assumes you're debugging and points the org service url at the proxy.aspx page.&amp;nbsp; This way the same silverlight app works on my dev machine and when it's deployed to CRM Online.&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 9.5pt;"&gt;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; (href.Contains(&lt;span style="color: #a31515;"&gt;"localhost"&lt;/span&gt;))&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Uri&lt;/span&gt; baseUrl = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Uri&lt;/span&gt;(href, &lt;span style="color: #2b91af;"&gt;UriKind&lt;/span&gt;.Absolute);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;&amp;nbsp;&amp;nbsp; orgServiceUrl = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Uri&lt;/span&gt;(baseUrl, &lt;span style="color: #a31515;"&gt;"SoapProxy/Proxy.aspx"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;&lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;&amp;nbsp;&amp;nbsp; orgServiceUrl = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Uri&lt;/span&gt;(location.GetProperty(&lt;span style="color: #a31515;"&gt;"protocol"&lt;/span&gt;) + &lt;span style="color: #a31515;"&gt;"//"&lt;/span&gt; + location.GetProperty(&lt;span style="color: #a31515;"&gt;"host"&lt;/span&gt;) + &lt;span style="color: #a31515;"&gt;"/xrmservices/2011/organization.svc/web"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;a href="https://docs.google.com/leaf?id=0BzDptMVvkXuwMWFlZTg5MzgtMTgxNi00NWYxLWI1MmUtYTk4OGYxZmNhZjhm&amp;amp;hl=en"&gt;Download the source code here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;-Erik&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2291594830244924527-6226297666172269924?l=erikpool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erikpool.blogspot.com/feeds/6226297666172269924/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erikpool.blogspot.com/2011/03/debugging-silverlight-web-resources.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/6226297666172269924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/6226297666172269924'/><link rel='alternate' type='text/html' href='http://erikpool.blogspot.com/2011/03/debugging-silverlight-web-resources.html' title='Debugging Silverlight web-resources that connect to CRM Online.'/><author><name>Erik Pool</name><uri>http://www.blogger.com/profile/07240189216754286258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2291594830244924527.post-7263221477913197194</id><published>2011-02-24T19:00:00.000-08:00</published><updated>2011-03-01T22:28:16.734-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Plug-Ins'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM'/><title type='text'>Plugin Registration Error: A proxy type with the name account has been defined by another assembly</title><content type='html'>So I ran into a very tricky error when building a custom tool to register CRM 2011 Plug-ins.&amp;nbsp; I wouldn't be surprised if other people run into the same issue when registering plug-ins programmatically. And its such a strange problem I thought it deserved an explanation.&lt;br /&gt;&lt;br /&gt;Here is the exception I got when retrieving a list of records from CRM:&lt;br /&gt;&lt;blockquote style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;A proxy type with the name account has been defined by another assembly. Current type: Plugins.Sdk.Account, Plugins, Version=1.0.1.0, Culture=neutral, PublicKeyToken=0b5679ac811dc738, Existing type: CrmSdk.Account, PluginRegisterTool, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null&lt;br /&gt;Parameter name: account&lt;/blockquote&gt;In this case I was retrieving a list of PluginAssembly records, but the same exception happens when I try to retrieve &lt;i&gt;ANY &lt;/i&gt;kind of entity.&amp;nbsp; Also note that "Plugins.Sdk.Account, Plugins" is a type in the plug-in assembly that I'm trying to register, and "CrmSdk.Account, PluginRegistrationTool" is the type in the application that's actually doing the registration.&lt;br /&gt;&lt;br /&gt;A look at the stack trace also gives us a hint about what's really happening here:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Server stack trace: &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; at Microsoft.Xrm.Sdk.AppDomainBasedKnownProxyTypesProvider.AddTypeMapping(Assembly assembly, Type type, String proxyName)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; at Microsoft.Xrm.Sdk.KnownProxyTypesProvider.LoadKnownTypes(Assembly assembly)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; at Microsoft.Xrm.Sdk.KnownProxyTypesProvider.RegisterAssembly(Assembly assembly)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; at Microsoft.Xrm.Sdk.KnownProxyTypesProvider.InitializeLoadedAssemblies()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; at Microsoft.Xrm.Sdk.AppDomainBasedKnownProxyTypesProvider..ctor()&lt;/span&gt;&lt;/blockquote&gt;&lt;b&gt;&lt;br /&gt;So what's really happening here? &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In order to register a plug-in I need to know certain information about the plug-in assembly, such as the version number, culture, and public key token. To get this info out of the assembly I use reflection:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;&lt;span style="color: #2b91af;"&gt;PluginAssembly&lt;/span&gt; assembly = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;PluginAssembly&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;&lt;span style="color: #2b91af;"&gt;Assembly&lt;/span&gt; dll = &lt;span style="color: #2b91af;"&gt;Assembly&lt;/span&gt;.LoadFile(path); &amp;nbsp;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;[] assemblyProp = dll.GetName().FullName.Split(&lt;span style="color: #a31515;"&gt;",= "&lt;/span&gt;.ToCharArray(), &lt;span style="color: #2b91af;"&gt;StringSplitOptions&lt;/span&gt;.RemoveEmptyEntries);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;assembly.Culture = assemblyProp[ASSEMBLY_PROP_CULTURE];&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;assembly.Name = assemblyProp[ASSEMBLY_PROP_NAME];&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;assembly.PublicKeyToken = assemblyProp[ASSEMBLY_PROP_PUBLICKEYTOKEN];&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;assembly.Version = assemblyProp[ASSEMBLY_PROP_VERSION]; &lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;b&gt;&lt;br /&gt;However, the Microsoft.Xrm.Sdk DLL is also doing its own reflection magic!&amp;nbsp; &lt;/b&gt;&lt;br /&gt;As soon as plug-in assembly is loaded into memory by Assembly.LoadFile(),&amp;nbsp; the Microsoft.Xrm.Sdk.KnownProxyTypesProvider will scan and cache all of the entity types in the assembly into its own internal collection.&amp;nbsp; The SDK assembly actually uses this information for converting the generic "Entity" records it gets back from CRM into strongly typed classes (e.g., account, contact, systemuser).&lt;br /&gt;&lt;br /&gt;Unfortunately the KnownProxyTypesProvider can only hold one "account" entity, and it doesn't differentiate between two "account" classes from different assemblies&amp;nbsp; (I'm not really sure if this should be considered a bug or not).&amp;nbsp;&amp;nbsp; And so I get an exception because I've filled up the KnownProxyTypesProvider with all the types from the plug-in assembly and not the entity types from the currently running application.&lt;br /&gt;&lt;br /&gt;To get around this issue you need to "prime" the KnownProxyTypesProvider with the correct entity types.&amp;nbsp; All you have to do is make sure you retrieve a record from CRM &lt;i&gt;before &lt;/i&gt;you load the plug-in assembly:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #2b91af; font-family: Consolas; font-size: 9.5pt;"&gt;QueryExpression&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt; query = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;QueryExpression&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;SystemUser&lt;/span&gt;.EntityLogicalName);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;query.PageInfo = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;PagingInfo&lt;/span&gt;() { Count = 1, PageNumber = 1 };&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;_serviceProxy.RetrieveMultiple(query);&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;This is a completely useless query, but the simple act of retrieving a single SystemUser prevents the KnownProxyTypesProvider from going loading the wrong types from the plug-in assembly. &lt;br /&gt;&lt;br /&gt;-Erik&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2291594830244924527-7263221477913197194?l=erikpool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erikpool.blogspot.com/feeds/7263221477913197194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erikpool.blogspot.com/2011/02/plugin-registration-error-proxy-type.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/7263221477913197194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/7263221477913197194'/><link rel='alternate' type='text/html' href='http://erikpool.blogspot.com/2011/02/plugin-registration-error-proxy-type.html' title='Plugin Registration Error: A proxy type with the name account has been defined by another assembly'/><author><name>Erik Pool</name><uri>http://www.blogger.com/profile/07240189216754286258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2291594830244924527.post-5835192511023009402</id><published>2011-02-13T16:02:00.000-08:00</published><updated>2011-03-01T22:29:10.697-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Plug-Ins'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM'/><title type='text'>CRM 2011 plug-in tips and tricks (part 2) - Testing plug-ins</title><content type='html'>&lt;span style="font-size: small;"&gt;Testing CRM plug-ins is now much easier than it was in previous version of CRM. &amp;nbsp; I will often create a simple console application that executes the plug-in I'm developing, just so I can make sure the core functionality of the plug-in works before I ever have to deploy it to the CRM server.&amp;nbsp; The same techniques can also be used for writing unit tests for your plug-ins. &amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;To create a simple test harness for your plug-ins you just need to create a few classes that implement the &lt;i&gt;IServiceProvider&lt;/i&gt;, &lt;i&gt;IOranizationServiceFactory&lt;/i&gt;, and &lt;i&gt;IPluginExecutionContext &lt;/i&gt;interfaces.&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;First is the &lt;b&gt;TestServiceProvider &lt;/b&gt;Class.&amp;nbsp; This class is responsible for providing the plugin execution context and service factory to the plug-in.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;public&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;TestServiceProvider&lt;/span&gt; : &lt;span style="color: #2b91af;"&gt;IServiceProvider&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;TestPluginContext&lt;/span&gt; _pluginContext;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; TestServiceProvider(&lt;span style="color: #2b91af;"&gt;TestPluginContext&lt;/span&gt; pluginContext)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _pluginContext = pluginContext;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;object&lt;/span&gt; GetService(&lt;span style="color: #2b91af;"&gt;Type&lt;/span&gt; serviceType)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (serviceType == &lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;IPluginExecutionContext&lt;/span&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; _pluginContext;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (serviceType == &lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;IOrganizationServiceFactory&lt;/span&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;TestServiceFactory&lt;/span&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;Next is the &lt;b&gt;TestServiceFactory &lt;/b&gt;class.&amp;nbsp; This class is responsible for generating the service proxy that the plug-in will be using.&amp;nbsp; For this example I am just returning a new OrganizationServiceProxy (from the referenced Microsoft.Xrm.Sdk.dll assembly), and I have hard-coded connection info. This means that when the plug-in runs, even in the test, it will still be hitting the CRM server. You could also easily return a "fake" organizationservice that didn't actually connect to the CRM server, but just verified that the plug-in was making the correct service calls.&amp;nbsp; &lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;public&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;TestServiceFactory&lt;/span&gt; : &lt;span style="color: #2b91af;"&gt;IOrganizationServiceFactory&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;IOrganizationService&lt;/span&gt; CreateOrganizationService(&lt;span style="color: #2b91af;"&gt;Guid&lt;/span&gt;? userId)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Uri&lt;/span&gt; serviceUrl = &lt;span style="color: blue;"&gt;new&lt;/span&gt; System.&lt;span style="color: #2b91af;"&gt;Uri&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"http://crmserver/org/xrmservices/2011/organization.svc"&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;ClientCredentials&lt;/span&gt; creds = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ClientCredentials&lt;/span&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; creds.Windows.ClientCredential = &lt;span style="color: blue;"&gt;new&lt;/span&gt; System.Net.&lt;span style="color: #2b91af;"&gt;NetworkCredential&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"username"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"pass"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"domain"&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;OrganizationServiceProxy&lt;/span&gt; _serviceProxy = &lt;span style="color: blue;"&gt;new&lt;/span&gt; Microsoft.Xrm.Sdk.Client.&lt;span style="color: #2b91af;"&gt;OrganizationServiceProxy&lt;/span&gt;(serviceUrl, &lt;span style="color: blue;"&gt;null&lt;/span&gt;, creds, &lt;span style="color: blue;"&gt;null&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(&lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ProxyTypesBehavior&lt;/span&gt;());&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; _serviceProxy;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;Finally, you have the &lt;b&gt;TestPluginContext &lt;/b&gt;class.&amp;nbsp; This is our fake plugin context that we will fill with the desired test information before executing the plug-in.&amp;nbsp; Note that I am making a WhoAmI request in the constructor to set the InitiatingUserId and OrganizationId properties.&amp;nbsp; This is mostly because I was testing several plug-ins that needed to use those two fields.&amp;nbsp; &lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: blue; font-family: Consolas;"&gt;public&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;TestPluginContext&lt;/span&gt; : &lt;span style="color: #2b91af;"&gt;IPluginExecutionContext&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; TestPluginContext()&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.InputParameters = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ParameterCollection&lt;/span&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.OutputParameters = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ParameterCollection&lt;/span&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//set the userid and the orgid on the context&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;IOrganizationService&lt;/span&gt; service = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;TestServiceFactory&lt;/span&gt;().CreateOrganizationService(&lt;span style="color: blue;"&gt;null&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;WhoAmIResponse&lt;/span&gt; whoAmI = (&lt;span style="color: #2b91af;"&gt;WhoAmIResponse&lt;/span&gt;)service.Execute(&lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;WhoAmIRequest&lt;/span&gt;());&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.InitiatingUserId = whoAmI.UserId;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.OrganizationId = whoAmI.OrganizationId;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;IPluginExecutionContext&lt;/span&gt; ParentContext { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt; Stage { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; } &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Guid&lt;/span&gt; BusinessUnitId { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Guid&lt;/span&gt; CorrelationId { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; } &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt; Depth { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Guid&lt;/span&gt; InitiatingUserId { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; } &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ParameterCollection&lt;/span&gt; InputParameters { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; IsExecutingOffline { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; } &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; IsInTransaction { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; IsOfflinePlayback { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; } &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt; IsolationMode { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; MessageName { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; } &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt; Mode { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt; OperationCreatedOn { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; } &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Guid&lt;/span&gt; OperationId { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Guid&lt;/span&gt; OrganizationId { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; } &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; OrganizationName { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ParameterCollection&lt;/span&gt; OutputParameters { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; } &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;EntityReference&lt;/span&gt; OwningExtension { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;EntityImageCollection&lt;/span&gt; PostEntityImages { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; } &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;EntityImageCollection&lt;/span&gt; PreEntityImages { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Guid&lt;/span&gt; PrimaryEntityId { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; } &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; PrimaryEntityName { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Guid&lt;/span&gt;? RequestId { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; } &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; SecondaryEntityName { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ParameterCollection&lt;/span&gt; SharedVariables { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; } &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Guid&lt;/span&gt; UserId { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;Now that we have the necessary classes set up, we can create a test.&amp;nbsp; To execute the plugin, you just create a new TestPluginContext and fill it with the data needed to test your plug-in.&amp;nbsp; Then create a new TestServiceProvider from the TestPluginContext, and then pass the service provider to the Execute method of your plug-in.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;TestPluginContext&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt; pluginContext = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;TestPluginContext&lt;/span&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;pluginContext.InputParameters[&lt;span style="color: #a31515;"&gt;"Target"&lt;/span&gt;] = user;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;pluginContext.PrimaryEntityName = &lt;span style="color: #a31515;"&gt;"systemuser"&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;pluginContext.MessageName = &lt;span style="color: #a31515;"&gt;"Update"&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;TestServiceProvider&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt; provider = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;TestServiceProvider&lt;/span&gt;(pluginContext);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;MyPlugin&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt; plugin = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;MyPlugin&lt;/span&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;plugin.Execute(provider);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-size: small;"&gt;Depending on the complexity of your plug-in, you may need to provide more information in the plug-in context.&amp;nbsp; In this example, I am testing a plug-in that fires whenever a user changes business units, and the plug-in requires a pre-image of the systemUser record:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Guid&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt; buid = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Guid&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"EF0C0FD0-B50B-E011-8E3F-001DD8B71C42"&lt;/span&gt;); &lt;span style="color: green;"&gt;//old businessunit&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Guid&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt; newBuid = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Guid&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"14880f34-711e-e011-b23e-001dd8b71c42"&lt;/span&gt;); &lt;span style="color: green;"&gt;//new businessunit&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Entity&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt; user = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Entity&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"systemuser"&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;user[&lt;span style="color: #a31515;"&gt;"businessunitid"&lt;/span&gt;] = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;EntityReference&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"businessunit"&lt;/span&gt;, newBuid);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;user[&lt;span style="color: #a31515;"&gt;"internalemailaddress"&lt;/span&gt;] = &lt;span style="color: #a31515;"&gt;"erik.pool@example.com"&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;user[&lt;span style="color: #a31515;"&gt;"fullname"&lt;/span&gt;] = &lt;span style="color: #a31515;"&gt;"Erik Pool"&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;user[&lt;span style="color: #a31515;"&gt;"systemuserid"&lt;/span&gt;] = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Guid&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"4C72C28A-5A0C-E011-892F-001DD8B71C42"&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;Entity&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt; preImage = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Entity&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"systemuser"&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;preImage[&lt;span style="color: #a31515;"&gt;"businessunitid"&lt;/span&gt;] = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;EntityReference&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"businessunit"&lt;/span&gt;, buid);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;preImage[&lt;span style="color: #a31515;"&gt;"internalemailaddress"&lt;/span&gt;] = &lt;span style="color: #a31515;"&gt;"erik.pool@example.com"&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;preImage[&lt;span style="color: #a31515;"&gt;"fullname"&lt;/span&gt;] = &lt;span style="color: #a31515;"&gt;"Erik Pool"&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;TestPluginContext&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt; pluginContext = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;TestPluginContext&lt;/span&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;pluginContext.InputParameters[&lt;span style="color: #a31515;"&gt;"Target"&lt;/span&gt;] = user;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;pluginContext.PreEntityImages = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;EntityImageCollection&lt;/span&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;pluginContext.PreEntityImages[&lt;span style="color: #a31515;"&gt;"Target"&lt;/span&gt;] = preImage;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;pluginContext.PrimaryEntityName = &lt;span style="color: #a31515;"&gt;"systemuser"&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;pluginContext.MessageName = &lt;span style="color: #a31515;"&gt;"Update"&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;TestServiceProvider&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt; provider = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;TestServiceProvider&lt;/span&gt;(pluginContext);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;SystemUserPostUpdatePlugin&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt; plugin = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;SystemUserPostUpdatePlugin&lt;/span&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;plugin.Execute(provider);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2291594830244924527-5835192511023009402?l=erikpool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erikpool.blogspot.com/feeds/5835192511023009402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erikpool.blogspot.com/2011/02/crm-2011-plug-in-tips-and-tricks-part-2.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/5835192511023009402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/5835192511023009402'/><link rel='alternate' type='text/html' href='http://erikpool.blogspot.com/2011/02/crm-2011-plug-in-tips-and-tricks-part-2.html' title='CRM 2011 plug-in tips and tricks (part 2) - Testing plug-ins'/><author><name>Erik Pool</name><uri>http://www.blogger.com/profile/07240189216754286258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2291594830244924527.post-8885717002474265893</id><published>2011-02-12T15:42:00.000-08:00</published><updated>2011-03-01T22:29:55.628-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sandbox'/><category scheme='http://www.blogger.com/atom/ns#' term='Plug-Ins'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM'/><title type='text'>CRM 2011 plug-in tips and tricks  (part 1)  -  Develop and Debug in Sandbox Isolation Mode</title><content type='html'>There are a lot of &lt;a href="http://msdn.microsoft.com/en-us/library/gg327861.aspx"&gt;examples &lt;/a&gt;of writing CRM 2011 plug-ins in the &lt;a href="http://msdn.microsoft.com/en-us/library/gg309408.aspx"&gt;SDK&lt;/a&gt;, but none of them really describe the process of testing, troubleshooting, and properly debugging you're plug-in code.&amp;nbsp; As a result I see a lot of developers wasting time and making guesses at the reasons for their plug-in errors. So in the following posts I will outline some of the gotchas and tricks I've learned so far while developing plug-ins for CRM 2011.&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #990000;"&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;#1.&amp;nbsp; Develop and Debug in Sandbox Isolation Mode (its faster)&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;If you ever want your plug-ins to work on CRM Online then you need to make sure you're plug-ins work in sandbox isolation mode.&amp;nbsp; And you will be surprised to learn&lt;a href="http://msdn.microsoft.com/en-us/library/gg334752.aspx"&gt; what works and doesnt work&lt;/a&gt; when in sandbox mode.&amp;nbsp; These are just a few of the things I've run into that don't work in sandboxed plug-ins&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Calling a web-service using &lt;a href="http://social.microsoft.com/Forums/en-US/crm2011beta/thread/86849e91-d4cb-4595-9c42-a7a00843621b"&gt;IP address or localhost&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Creating the WCF service proxy class by calling its constructor.&lt;/li&gt;&lt;li&gt;&lt;a href="http://social.microsoft.com/Forums/en-US/crm2011beta/thread/0cea27a1-b146-4e73-b440-b7727055aba0"&gt;CRM LINQ queries&lt;/a&gt;&amp;nbsp;&lt;/li&gt;&lt;li&gt;Calling a web service using default credentials&lt;/li&gt;&lt;/ul&gt;The best way to avoid being surprised by any of these issues is to make sure you do all development in testing in Sandbox mode.&amp;nbsp; You don't want to be surprised when you deploy your plug-in to CRM Online and find out you're using some .NET function that isn't supported.&lt;br /&gt;&lt;br /&gt;Also,&lt;span style="color: red;"&gt; &lt;b style="color: black;"&gt;it is now actually easier to debug plug-ins when they are sand-boxed. &lt;/b&gt;&lt;/span&gt;When &lt;a href="http://msdn.microsoft.com/en-us/library/gg309620.aspx"&gt;registering a plug-in&lt;/a&gt;, you have three options of where the plug-in can be stored.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;On Disk - The plug-in assembly is stored on the CRM server file system (in the Server\Bin\Assembly folder).&amp;nbsp;&lt;/li&gt;&lt;li&gt;Database - The plug-in assembly is actually uploaded to the CRM server and stored in the CRM database.&lt;/li&gt;&lt;li&gt; GAC - The plug-in is stored in the global assembly cache on the CRM server.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;In previous versions of CRM if you wanted to debug a plug-in your only option was to register the plug-in on DISK.&amp;nbsp; This meant that everytime you made a change to your plug-in code you had to re-copy the file to the assembly folder&amp;nbsp; (which also meant you had to restart IIS and the CRM Asynchronous service).&lt;br /&gt;&lt;br /&gt;Now you can debug the plug-in even if it's stored in the database and in sandbox mode, and&lt;b&gt; it's actually a much faster development cycle because you can avoid restarting IIS and the Asyc service.&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Debugging a plug-in is simple, just follow the instructions in the SDK found &lt;a href="http://msdn.microsoft.com/en-us/library/gg328574.aspx#bkmk_sandboxplugin"&gt;here&lt;/a&gt;.&amp;nbsp; Essentially, there are three differences from debuggin an on-disk plug-in&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Add the SandboxDebugPlugins key to the registery (see the &lt;a href="http://msdn.microsoft.com/en-us/library/gg328574.aspx#bkmk_sandboxplugin"&gt;instructions &lt;/a&gt;in the SDK).&lt;/li&gt;&lt;li&gt;Copy the PDB file for your plug-in assembly to the server\bin\assembly folder.&lt;/li&gt;&lt;li&gt;In Visual Studio, attach the debugger to all of the "Microsoft.Crm.Sandbox.WorkerProcess.exe" processes.&lt;/li&gt;&lt;/ol&gt;It is actually un-necessary to reset IIS or the sandbox processes when making changes to your plug-in, all you need to do is copy the new PDB to assembly folder and re-upload the new plug-in DLL to the server.&lt;br /&gt;&lt;br /&gt;In fact, you can make the process of re-uploading the plug-in DLL to CRM very fast with a simple console application. All the console app needs to do is connect to the CRM server, and update the "Content" attribute of the &lt;a href="http://msdn.microsoft.com/en-us/library/gg334529.aspx"&gt;PluginAssembly&lt;/a&gt; record for your plug-in. The following code should do the trick:&lt;br /&gt;&lt;br /&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: #2b91af; font-family: Consolas;"&gt;QueryExpression&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt; query = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;QueryExpression&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;PluginAssembly&lt;/span&gt;.EntityLogicalName);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;query.ColumnSet = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ColumnSet&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"name"&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;query.Criteria.Conditions.Add(&lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ConditionExpression&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"name"&lt;/span&gt;, &lt;span style="color: #2b91af;"&gt;ConditionOperator&lt;/span&gt;.Equal, myAssemblyName));&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: #2b91af;"&gt;EntityCollection&lt;/span&gt; retrievedAssemblies = _serviceProxy.RetrieveMultiple(query);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; (retrievedAssemblies.Entities.Count &amp;gt; 0)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;PluginAssembly&lt;/span&gt; myAssembly = (&lt;span style="color: #2b91af;"&gt;PluginAssembly&lt;/span&gt;)retrievedAssemblies.Entities[0];&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;byte&lt;/span&gt;[] bytes = &lt;span style="color: #2b91af;"&gt;File&lt;/span&gt;.ReadAllBytes(myAssemblyPath);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; myAssembly.Content = &lt;span style="color: #2b91af;"&gt;Convert&lt;/span&gt;.ToBase64String(bytes);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _serviceProxy.Update(myAssembly);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Consolas;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;If you also automate the copying of the PDB file into the server\bin\assembly folder then you can actually get at pretty quick debugging cycle going. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2291594830244924527-8885717002474265893?l=erikpool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erikpool.blogspot.com/feeds/8885717002474265893/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erikpool.blogspot.com/2011/02/crm-2011-plug-in-tips-and-tricks-part-1.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/8885717002474265893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/8885717002474265893'/><link rel='alternate' type='text/html' href='http://erikpool.blogspot.com/2011/02/crm-2011-plug-in-tips-and-tricks-part-1.html' title='CRM 2011 plug-in tips and tricks  (part 1)  -  Develop and Debug in Sandbox Isolation Mode'/><author><name>Erik Pool</name><uri>http://www.blogger.com/profile/07240189216754286258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2291594830244924527.post-5788394897843949463</id><published>2010-12-28T15:14:00.000-08:00</published><updated>2011-03-01T22:30:28.210-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SOAP'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM'/><title type='text'>How to use the CRM 2011 Organization (SOAP) Service from Silverlight</title><content type='html'>&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;Now that the &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=c3f82c6f-c123-4e80-b9b2-ee422a16b91d&amp;amp;displaylang=en"&gt;CRM 2011 RC1&lt;/a&gt; is out it’s finally possible to use the &lt;a href="http://en.wikipedia.org/wiki/SOAP"&gt;SOAP &lt;/a&gt;web service from Silverlight applications that are deployed as web-resources to the CRM server.&amp;nbsp; The SOAP service offers a number of advantages over the other REST service, such as the ability to retrieve CRM metadata, execute fetchxml queries, and the ability to work with dynamic entity objects instead of strongly typed classes.&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;Unfortunately the &lt;a href="http://offers.crmchoice.com/Redirect.aspx?EQ=773ed3059447707d0c401f60fdc01fed36b1cf4b802e229407320fe1323f25f34310d9378afa71d0830c507d111f15201525c8e8958059db40362d58369cceb1ca65eca0eabb148cecd6d8fa25205ad8e9d7539c9f16d1520f6951286ea1f1fc54d3b1e391a537281fcc5be3a013cbf9be153f0a6d081f4cdc02c9c9164b596fe5f7424c19644c5ada8ec01e6d9e68f0abf1ffc6d29927f81a0983c33e2a4ac3d1e1dc1c55f47a13ed7788d171578f27794abd83fcd2dc1333caf6e14d5ba32a05df2276b5fa20a1"&gt;SDK &lt;/a&gt;still doesn’t provide much information, and a number of people have been &lt;a href="http://social.microsoft.com/Forums/en/crm2011beta/thread/89a2cf1c-182b-4c24-b27b-43af13a7d2af"&gt;asking&lt;/a&gt; in the beta forums about how to get this working.&amp;nbsp; The page titled “Use the SOAP endpoint for Silverlight clients” currently just says “Content coming soon”.&amp;nbsp; On top of that there are still a couple of serialization bugs that prevent certain SDK messages from working correctly when sent from a Silverlight client.&amp;nbsp; But we can get around these bugs with a couple tricks.&amp;nbsp; Here’s how you do it:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;Add the Organization service as a Service Reference to your Silverlight project&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt; &lt;br /&gt;&lt;br /&gt;First you need to add the service reference. You can do this the same way you would add a reference for the REST service.&amp;nbsp; In CRM, go to Settings -&amp;gt; Customizations -&amp;gt; Developer Resources, and download the WSDL file for the organization service. Then in your Silverlight project click Add Service Reference, and enter the path to the wsdl file you downloaded.&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;Fixing the service reference classes&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;br /&gt;Now that we have the service reference, we need to make some modifications to it to get around those serialization bugs.&amp;nbsp; Without these changes some of the SDK messages (such as retrieving metadata) will fail.&amp;nbsp; Microsoft has already indicated that they are working on these issues, so hopefully these changes are just be a temporary workaround until it gets fixed for real.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;The main problem is that the Reference.cs file generated by Visual Studio doesn’t serialize the requests in the same format that CRM is expecting, but we can fix this by making some modifications to Reference.cs.&amp;nbsp; Find the Reference.cs file that was generated by Visual Studio when you added the service reference and open it in Visual Studio.&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;br /&gt;The first issue is that the reference doesn’t create serializers for certain classes. When trying to retrieve metadata you will see a "Type 'EntityFilters' with data contract name 'EntityFilters:http://schemas.microsoft.com/xrm/2011/Metadata' is not expected" error.&amp;nbsp; You can fix this by adding a knownTypeAttribute to the OrganizationRequest class, like this:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;[System.Runtime.Serialization.&lt;span style="color: #2b91af;"&gt;KnownTypeAttribute&lt;/span&gt;(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;EntityFilters&lt;/span&gt;))]&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;public&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt; &lt;span style="color: blue;"&gt;partial&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;OrganizationRequest&lt;/span&gt; : &lt;span style="color: blue;"&gt;object&lt;/span&gt;, System.ComponentModel.&lt;span style="color: #2b91af;"&gt;INotifyPropertyChanged&lt;/span&gt; {&lt;/span&gt;  &lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;br /&gt;You will also need to add the following KnownTypeAttribute to the OrganizationResponse class:&lt;/span&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;[System.Runtime.Serialization.&lt;span style="color: #2b91af;"&gt;KnownTypeAttribute&lt;/span&gt;(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;EntityMetadata&lt;/span&gt;))]&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;public&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt; &lt;span style="color: blue;"&gt;partial&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;OrganizationResponse&lt;/span&gt; : &lt;span style="color: blue;"&gt;object&lt;/span&gt;, System.ComponentModel.&lt;span style="color: #2b91af;"&gt;INotifyPropertyChanged&lt;/span&gt; {&lt;/span&gt;  &lt;br /&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;Note: These are the only two KnownTypeAttributes I had to add, but I didn’t test every possibly type of CRM SDK message. It’s possible that other SDK message will require adding more KnownTypeAttributes to the reference.cs file.&amp;nbsp; Fortunately the error message you will get is pretty descriptive and will tell you which type you need to add the KnownTypeAttribute for.&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;UPDATE:&amp;nbsp; you will also need to add the following KnownTypeAttributes to the Entity class:&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;pre&gt;[System.Runtime.Serialization.KnownTypeAttribute(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(OptionSetValue))]&lt;br /&gt;[System.Runtime.Serialization.KnownTypeAttribute(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(EntityReference))]&lt;br /&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;partial&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; Entity : &lt;span style="color: blue;"&gt;object&lt;/span&gt;, System.ComponentModel.INotifyPropertyChanged&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The second issue is the way that it serializes the KeyValuePair class.&amp;nbsp; For some reason it serializes them as "Key" and "Value" (with capitalization), while CRM will only accept "key" and "value" (all lowercase).&amp;nbsp; To get around this you can create your own KeyValuePair class and replace all references to System.Collections.Generic.KeyValuePair in Reference.cs with your own class.&amp;nbsp; So first create the following class (I just put this class in the same namespace as the rest of the classes in Reference.cs):&lt;/span&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;[&lt;span style="color: #2b91af;"&gt;DataContract&lt;/span&gt;(Name = &lt;span style="color: #a31515;"&gt;"KeyValuePairOfstringanyType"&lt;/span&gt;, Namespace = &lt;span style="color: #a31515;"&gt;"&lt;a href="http://schemas.datacontract.org/2004/07/System.Collections.Generic"&gt;http://schemas.datacontract.org/2004/07/System.Collections.Generic&lt;/a&gt;"&lt;/span&gt;)]&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;public&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;KeyValuePair&lt;/span&gt;&amp;lt;TKey, TValue&amp;gt;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;{&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; KeyValuePair(TKey key, TValue value)&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;._key = key;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;._value = value;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; TKey _key;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; TValue _value;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;DataMember&lt;/span&gt;(Name = &lt;span style="color: #a31515;"&gt;"key"&lt;/span&gt;)]&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; TKey Key&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;get&lt;/span&gt; { &lt;span style="color: blue;"&gt;return&lt;/span&gt; _key; }&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;set&lt;/span&gt; { _key = &lt;span style="color: blue;"&gt;value&lt;/span&gt;; }&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #2b91af;"&gt;DataMember&lt;/span&gt;(Name = &lt;span style="color: #a31515;"&gt;"value"&lt;/span&gt;)]&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; TValue Value&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;get&lt;/span&gt; { &lt;span style="color: blue;"&gt;return&lt;/span&gt; _value; }&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;set&lt;/span&gt; { _value = &lt;span style="color: blue;"&gt;value&lt;/span&gt;; }&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;}&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 9.5pt;"&gt;&lt;/span&gt;  &lt;br /&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;Then do a find-and-replace in the Reference.cs file and replace "System.Collections.Generic.KeyValuePair" with "[yournamespace].KeyValuePair".&amp;nbsp;&amp;nbsp; The new KeyValuePair class will actually serialize the way CRM wants it to, and you will be able to execute requests.&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;UPDATE:&amp;nbsp; Don't replace every instance of KeyValuePair in the reference.cs file.&amp;nbsp; You actually do not want to replace any of the KeyValuePairs that appear inside KnownTypeAttribute attributes.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br style="color: red;" /&gt; &lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;Use the service reference&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;br /&gt;To use the service you need to have the correct binding.&amp;nbsp; The following code will set up the binding correctly for an on-premise installation:&lt;/span&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;String&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas; font-size: 8pt;"&gt; &lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;url =&lt;span style="color: #2b91af;"&gt; &lt;/span&gt;&lt;span style="color: #a31515;"&gt;"&lt;a href="http://myserver/myOrganization/xrmservices/2011/organization.svc/web"&gt;http://myServer/myOrganization/xrmservices/2011/organization.svc/web&lt;/a&gt;"&lt;/span&gt;;&lt;span style="color: #a31515;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;BasicHttpBinding&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt; binding = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;BasicHttpBinding&lt;/span&gt;(&lt;span style="color: #2b91af;"&gt;BasicHttpSecurityMode&lt;/span&gt;.None);&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;binding.MaxReceivedMessageSize = 2147483647;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas; font-size: 8pt;"&gt;&lt;br /&gt;OrganizationServiceClient&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt; client = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;OrganizationServiceClient&lt;/span&gt;(binding, &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;EndpointAddress&lt;/span&gt;(url));&lt;/span&gt;  &lt;br /&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;There are three interesting thing in here. First, notice is that the url has “/web” on the end of it. This is required for the organization service to work from Silverlight.&amp;nbsp; Second, notice that the binding is using the “None” security mode, because the URL is using the HTTP scheme.&amp;nbsp; If you need to connect over HTTPS then you will need to use BasicHttpSecurityMode.&lt;i&gt;Transport &lt;/i&gt;instead of BasicHttpSecurityMode.&lt;i&gt;None&lt;/i&gt;.&amp;nbsp;&amp;nbsp; CRM Online always uses HTTPs so it will always require the Transport security mode.&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;br /&gt;Also, if you’re using CRM Online you will need to make sure the URL has the exact same domain as the page hosting the Silverlight application.&amp;nbsp; The CRM documentation claims you should connect to [organization].api.crm.dynamic.com, but this won’t work because the Silverlight application you deploy as a web resource will not be on that domain.&amp;nbsp; The domain used for web-resources won’t have the “.api” in it, so your web-service URL should be the same. &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;Executing service requests&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;br /&gt;Making requests to the organization service from Silverlight is almost the same as from C# code.&amp;nbsp; The main difference is that you do not have the strongly typed entity classes that are generated by CrmSvcUtil.exe, and you do not have any of the strongly typed message classes found in Microsoft.Xrm.Sdk.dll.&amp;nbsp; For Create, Update, and Retrieve messages you will have to use the late-bound Entity class, and set attributes using the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;entity[“propertyname”] = value&lt;/span&gt; syntax. &lt;/span&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;br /&gt;For Execute messages, you will have to use the dynamic OrganizationRequest class, and add all the parameters required for each specific message.&amp;nbsp; For example, the following will retrieve metadata for the account entity:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;private&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; button1_Click(&lt;span style="color: blue;"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af;"&gt;RoutedEventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;OrganizationServiceClient&lt;/span&gt; client = GetOrganizationService();&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;OrganizationRequest&lt;/span&gt; req = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;OrganizationRequest&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; req.RequestName = &lt;span style="color: #a31515;"&gt;"RetrieveEntity"&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; req.Parameters = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ParameterCollection&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; req.Parameters.Add(&lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;, &lt;span style="color: blue;"&gt;object&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515;"&gt;"LogicalName"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"ae_tasker"&lt;/span&gt;));&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; req.Parameters.Add(&lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;, &lt;span style="color: blue;"&gt;object&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515;"&gt;"EntityFilters"&lt;/span&gt;, &lt;span style="color: #2b91af;"&gt;EntityFilters&lt;/span&gt;.Attributes));&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; req.Parameters.Add(&lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;, &lt;span style="color: blue;"&gt;object&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515;"&gt;"MetadataId"&lt;/span&gt;, &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Guid&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"00000000-0000-0000-0000-000000000000"&lt;/span&gt;)));&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; req.Parameters.Add(&lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;, &lt;span style="color: blue;"&gt;object&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515;"&gt;"RetrieveAsIfPublished"&lt;/span&gt;, &lt;span style="color: blue;"&gt;false&lt;/span&gt;));&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; client.ExecuteCompleted += &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;EventHandler&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af;"&gt;ExecuteCompletedEventArgs&lt;/span&gt;&amp;gt;(client_ExecuteCompleted);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; client.ExecuteAsync(req);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;void&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt; client_ExecuteCompleted(&lt;span style="color: blue;"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af;"&gt;ExecuteCompletedEventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="IT" style="font-family: Consolas; font-size: 8pt;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="IT" style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;EntityMetadata&lt;/span&gt; data = (&lt;span style="color: #2b91af;"&gt;EntityMetadata&lt;/span&gt;)e.Result.Results[0].Value;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="IT" style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: blue; font-family: Consolas; font-size: 8pt;"&gt;string&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt; s = &lt;span style="color: #a31515;"&gt;"attributes: "&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;for&lt;/span&gt; (&lt;span style="color: blue;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 10; i++)&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; s += data.Attributes[i].LogicalName + &lt;span style="color: #a31515;"&gt;", "&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;MessageBox&lt;/span&gt;.Show(s);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family: Consolas; font-size: 8pt;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;Update: Added an example silveright application making SOAP requests to CRM (including source code and all the changes made to the reference.cs file).&amp;nbsp; You can download it &lt;a href="https://docs.google.com/leaf?id=0BzDptMVvkXuwMzVhN2RkZjAtMWFlMC00MDU1LTkwZWEtYTdiODZiMGE5YjUx&amp;amp;hl=en"&gt;here&lt;/a&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2291594830244924527-5788394897843949463?l=erikpool.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erikpool.blogspot.com/feeds/5788394897843949463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erikpool.blogspot.com/2010/12/how-to-use-crm-2011-organization-soap.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/5788394897843949463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2291594830244924527/posts/default/5788394897843949463'/><link rel='alternate' type='text/html' href='http://erikpool.blogspot.com/2010/12/how-to-use-crm-2011-organization-soap.html' title='How to use the CRM 2011 Organization (SOAP) Service from Silverlight'/><author><name>Erik Pool</name><uri>http://www.blogger.com/profile/07240189216754286258</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
