CRM Blog

Open vs. Scheduled Appointments In CRM
by Danny Varghese 01.23.09

Comments    No Comments

In CRM, when creating appointments, you can set the status to Open or Scheduled.  But why would a user set the status to one or the other?

 

According to the SDK, the status and state codes are different:

 

 

 

For CRM Outlook users, the only real difference seems to be the scheduling.  When other users look at your calendar during this time period, if the appointment was marked Open, the time block will be marked as "tentative."  If the appointment was marked Scheduled, the time will show up as "busy" in Outlook.

Filed under:
Using CRM Workflow To Create Audit Trail
by Danny Varghese 01.20.09

Comments    No Comments

 

There's an excellent post on the MSDN CRM blog on how to create an audit trail using the CRM 4.0 workflow.  I've had numerous customer requests for an audit trail of entities when a field changes.  Clients want to know when certain fields change, and who made the change. 

 

The MSDN post gives a great example of using out of the box CRM workflow functionality to meet their needs: http://blogs.msdn.com/crm/archive/2008/04/10/using-workflow-to-maintain-an-audit-log.aspx.

Infinite Loop In CRM Workflow Custom Assembly
by Danny Varghese 01.19.09

Comments    2 Comment(s)

 

Business Requirement

I recently had a requirement where if an account's address was updated, all associated contact's addresses needed to be updated as well.  Likewise, if a contact gets re-associated to another account, i.e. the parentcustomerid field gets changed, then update that contact's address.

 

Initial Development

I thought we could use a CRM custom workflow activity to handle this because it gives the business user the ability to configure the workflow.   So I created two separate workflows that would call a custom workflow activity assembly.  The trigger to call the account workflow was if any of the address attributes changed, and for contact was if the parentcustomerid was set/changed.

 

The assembly itself first checked the workflow context to see what the primary entity was (to handle being called from the account or contact workflow).  Then the required business logic was performed, and the CRM web service update was called to update the contact entity.

 

Test Results

After I registered the assembly and started unit testing, it looked as if everything worked. Then looking at the history of workflows for the test contact record, I noticed about six entries for the workflow I just configured.  Then I used a VPC and tested the assembly by using Visual Studio debugger, attaching it to the CRM Asynchronous  Service process,  and found that there was an infinite loop occurring.

 

When the contact record was re-associated to another account, the workflow kicked off and executed the custom assembly.  Within the code, it set only the address properties on that record and then called the CRM service update method.  Right after that update was made, a new workflow instance was called again.  To make sure, I commented out the update call in the code and…no more loops!

 

Final Thoughts

Some technologies have flags for attributes to determine if that particular attribute has been updated or not.  When the CRM web service update was called, even though I only set the address fields, it seems to "flag" that all attributes have been updated.  Either that, or the workflow conditions were never checked. 

 

I even tried to add some sort of check to make sure even if the workflow was called the code wasn't executed.  However, unlike plug-ins, workflows don't have functionality to check the values before and after an update.  I also tried putting a global counter to update after the first run, and check if the method was called again.  However, the entire workflow was called again, which created another instance of the class, thus the counter idea didn't work.

 

Solution

I finally ended up using a plug-in, which you can configure to run asynchronously if you heart desires.  In the future, I now know that a workflow should not be setup to call a custom assembly that updates that same record.  The CRM web service update will cause infinite loops, and is better handled via a plug-in.

Filed under:
CRM WebService Error: Only one usage of each socket address (protocol/network address/port) is normally permitted
by Luke Simpson 01.15.09

Comments    7 Comment(s)

When performing a data integration or migration into CRM, it is very common to create a .Net application that transforms the data, then pushes the records into CRM using the WebServices.  At times, however, the load of data being pushed to IIS can be more than is acceptable to the default settings in an IIS implementation.  At these high load times, the server might post an error stating "Only one usage of each socket address (protocol/network address/port) is normally permitted (typically under load)."

What is happening, is that connections are being repeatedly opened and closed on the webserver.  When a connection is closed, the connection goes into a TIME_WAIT state for 240 seconds.  This is the default setting.  In this case, the IP being used is typically fixed, which means that the variable is the local port.  By default ports 1024-5000 are available to be used, which means that using default setting you have approximately 4000 ports to be used during a 4 minute span (240 seconds).  So if your code is making more than 16 webservice calls per second, you will exhaust all of the available ports!

 To fix this problem, you can make 2 different registry changes on the CRM Application Server.

  1. Increase the dynamic port range.  As stated above, the default is 5000 but this can be raised up to 65534.
    • Using Regedit, navigate to  HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters\MaxUserPort (if this key does not exist, create it as DWORD value)
    • Set the value to 65534, or a value of your choice
  2. Reduce the amount of time that the connection is in a TIME_WAIT state.
    • Using Regedit, navigate to  HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters\TCPTimedWaitDelay (if this key does not exist, create it as DWORD value)
    • Set the value to 30

 By performing the actions above, you are allowing the server to use a far larger number of available ports, and you also allow the server to recycle them faster.  Problem solved!
Filed under:
IE Enhanced Security Configuration interferes with CRM
by Luke Simpson 01.08.09

Comments    No Comments

If you are having problems selecting colums to edit/remove from a view in CRM, then the Internet Explorer Enhanced Security Configuration may be the culprit.  In IE 6 it is called Internet Security Configuration.  A fix that I found worked and you may want to consider, is to go to Add/Remove Programs on the CRM server, select Add/Remove Windows Components and uninstall the Enhanced Security Configuration.  After it has been uninstalled, perform an IIS reset (sometimes you need to reboot the server) and you should be good to go, however removing this could have other security related consequences and should be reviewed thoroughly.

Filed under:
Formatting Mail Merge fields in CRM 4.0 Mail Merge
by Zahara Hirani 01.05.09

Comments    No Comments

 

Recently, I had to do some custom formatting for mail merge documents in CRM 4.0 and here are a few format examples:

Formatting a Date:
         {MERGEFIELD "MyDate" \@ "M/d/yyyy" \*MERGEFORMAT}

If you just wanted to add the current date when creating the document:
         {DATE  \@ "M/d/yyyy"}

Formatting a number as a currency value:
         {MERGEFIELD "MyAmount" \# "$0.00" \*MERGEFORMAT}

Formatting a number as a percentage value:
         {MERGEFIELD "MyPercent" *100  \# "0%" \*MERGEFORMAT}

Formatting a number with a specific format:
         {MERGEFIELD "MyAccountNumber" \# "00 00 000" \*MERGEFORMAT}

Enjoy!!

Filed under:
Creating a Differencing Disk For CRM VPC Images
by Danny Varghese 01.02.09

Comments    No Comments

 Intro

    Ever since I started learning about and developing for Microsoft CRM, I've used VPC (virtual pc) images to develop and test customizations, workflows, security roles, etc.  Often times I would have to copy the virtual hard drive multiple times for multiple clients.

     

    Differencing disks allow you to create a new disk off of a parent disk, but going forward, all changes made to that disk are saved to the new disk.  This will allow you to have multiple virtual machines setup, but only using one parent virtual hard drive. 

     

    Steps To Create Differencing Disk

    1. Create Virtual Hard using the wizard via the Virtual PC Console

 

 

    1. Click Next | Create New Virtual Disk | A Virtual Hard Disk.
    2. Choose a location for where you want this to be stored.
    3. Choose the Differencing Disk option.
  •  
  •  

    1. Select the parent virtual hard drive | Click Finish
    2. Next to create a virtual machine use the virtual machine wizard

     

     

     

    1. Click Next | Create Virtual Machine | Next
    2. Browse to a location to save the virtual machine
    3. Set the operating system | Set the memory required
    4. Select an existing virtual hard disk | Next
    5. Browse and select the virtual hard disk created in steps (1) - (5).
    6. Click Finish

     

    You have now created a differencing disk!

Filed under:
State Code Attribute Data Type When Accessed Inside Plug-In
by Danny Varghese 12.29.08

Comments    No Comments

 How To Access Attributes Within Plug-In Code

When developing plug-ins, users can access fields on the form before and after the record has been updated, created, etc.  Developers can do this by first registering the assembly, then a step (configuring whether it's a post/pre update/create/etc., then finally by registering a pre/post image.  The image(s) is/are passed in with the execution context.  When configuring the image, one can select attributes that get passed in.

 

When developing the actual plug-in, these attributes can be accessed in the following manner:

 

entityImageName = (DynamicEntity)context.PostEntityImage[<postEntityImageName>];

attributeName = (DataType)entityImageName[<attributeName>].Value;

 

For example, if the attribute is a lookup…

 

DynamicEntity entityImageName = (DynamicEntity)context.PostImageEntity["testImage"];

Lookup testLookup = (Lookup)entityImageName["testLookupAttributeName"].Value;

 

If you look at the above code, the context has access to the pre/post images based on whatever you configured using the plug-in registration tool.  The name you configured is the "postEntityImageName," This is then all cast to a DynamicEntity.  Then you can access the attributes, much like an array or collection, using the attribute name.  However, since the ".Value" method returns an object, it must be cast to the appropriate data type.  The data type can be found in the customization section on the CRM client, or when registering a plug-in image, the data types are found when you need to select/de-select attributes to pass in.

 

State Code Attribute

For most attributes, the data types are straight forward.  The data type for the id of the record is a Key, for any referential or parental relationship attributes, the data type is a Lookup, and for the Status attribute, the data type is simply Status.  However, the State Code can be tricky and after trial and error, I've found that when you need to access the State Code attribute, you must cast this as a String.  The two possible values that is out-of-the-box is "Active," and "Inactive."

Filed under:
Microsoft CRM 4.0 and Windows Presentation Foundation
by Jeremy Hofmann 12.26.08

Comments    No Comments

Interesting in building a dashboard for CRM 4.0?  In this article, I’ll show you how to build your own custom CRM dashboards, using Microsoft’s Windows Presentation Foundation to construct the user interface.  This dashboard will run as a standalone Windows application in order to give your user’s the most optimal performance.

Please visit the Microsoft CRM Team blog for the whole article - http://blogs.msdn.com/crm/archive/2009/01/07/building-rich-client-dashboards-for-microsoft-dynamics-crm-with-windows-presentation-foundation.aspx

 Enjoy!

 

Developing Portable Code For Microsoft CRM - Part II
by Danny Varghese 12.23.08

Comments    No Comments

 Intro

As mentioned in one of my earlier blog articles: http://www.crowehorwath.com/cs/blogs/crm/archive/2008/03/05/gac-it-developing-portable-code-for-microsoft-crm.aspx one can register assemblies in the GAC to help build a portable custom CRM solution.  In CRM 4.0, with the introduction of registering assemblies on the database server, developing portable code has gotten a bit easier. 

 

Building A Common Library

When developing plug-ins, often times developers find themselves either re-writing or re-using some common functionality.  For example connecting to a database, executing stored procedures, logging to a log file, even creating/updating entities.  When encountering these situations, I would recommend extracting out this logic and placing it in it's own assembly file acting as a library.  This then can be called by multiple assemblies/plug-ins thus reducing the amount of overall code, and maintenance.

 

Referencing The Common Library
When developing a plug-in, the best way to reference the library you've built is adding it as a project reference.  According to MSDN (http://msdn.microsoft.com/en-us/library/wkze6zky(VS.80).aspx) you should avoid adding file references to outputs of another project in the same solution, because doing so may cause compilation errors. Instead, use the Projects tab of the Add Reference dialog box to create project-to-project references. This makes team development easier, by allowing for better management of the class libraries you create in your projects.

 

Putting It All Together

Once you've developed your plug-in/custom assembly for CRM and the library, it's time to put it all together.  **NOTE**  Since plug-ins need to be strong typed, so do any files that it references.  So the library, if you're using it for plug-ins, will need to be strong typed.  First register the plug-in assembly file either on the database/server.  Then place the library in the <crm-root>\server\bin\assembly directory.  By doing this, anytime the plug-in executes, it will check this directory for the reference.  What this allows you to do is very easily develop a library to be used by all plug-ins and you don't have to use the GAC!  Happy coding!

Filed under:
Using Fiddler for CRM Development and Troubleshooting
by Jeremy Hofmann 12.19.08

Comments    No Comments

Microsoft CRM is a web application.  That means it uses a variety of resources such as html pages, javascript, css style sheets, and images to render the user interface.  Occassionally during development or troubleshooting you will need to view these resources, the order they are streamed to the browser, and how long each request is taking.  Armed with this knowledge, you can fine tune your CRM application to optimal performance.  Or, you can determine where certain page elements are located which enables you to code some fancy customizations.

Fiddler is a web debugging proxy that allows you to inspect the traffic between the web server and the client.  It's quick and easy to install.  You can record and save your sessions for later viewing, or even save them as Visual Studio web tests for later analysis and playback.

Notice on the left, Fiddler shows you the exact url, size, and source of the file.  It also lists each HTTP response associated with the request.  You can use this information to tweak file cache and to see exactly what the browser is trying to do as you navigate CRM.  On the right, you can view statistics, session information, and the actual html pages that are sent from the server. 

Finally, you can use Fiddler to capture web service calls, which will help you author client side javascript.  For a tutorial on this, see the Microsoft CRM SDK article here.

Enjoy!

Filed under:
CRM Webinar
by Bryan Van Antwerp 12.17.08

Comments    No Comments

Crowe is providing a webinar on Microsoft Dynamics CRM on January 8, 2009 from 1:00 - 2:30 PM ET.  If you are interested, you can click here for more details: 

https://www.crowehorwath.com/crowe/AboutUs/Events/detail.cfm?id=413

Filed under:
Changing the Domain and/or Username in CRM 4.0
by Luke Simpson 12.16.08

Comments    1 Comment(s)

Microsoft has changed the way administrators may alter an existing user's Domain and/or Username in CRM 4.0.  A knowledge base article exists with detailed instructions, which can be found here: http://support.microsoft.com/kb/930853.

 Here is a quick synopsis of the procedure:

  1. Modify the user account in Active Directory. For example, change the user name, and then change the logon name.
  2. Open Microsoft Dynamics CRM 4.0 as a System Administrator user.
  3. Click Settings, click Administration, click Users, and then open the user record that you want to change.
  4. In the Domain Logon Name box, type an Active Directory user account that is not used by a Microsoft Dynamics CRM 4.0 user record.
    ~~This should just be any AD user on the network that is not using CRM.  It is just a placeholder.

    Note If all the Active Directory user accounts are used by Microsoft Dynamics CRM 4.0 user records, create a temporary Active Directory user account.
  5. Click Save.
  6. In the Domain Logon Name box, type the Active Directory user account. Then, click Save and Close.  
    ~~This should be the new Username that you wish to use.

    Note The Active Directory user account that you type in this step is the account that is used by a Microsoft Dynamics CRM 4.0 user record. The Microsoft Dynamics CRM 4.0 user record is the record for which you want to change the user name and the logon name in Microsoft Dynamics CRM 4.0.
Filed under:
Modifying the Planning Tasks View on a Marketing Campaign
by Shelley Lane 12.14.08

Comments    No Comments

Each Campaign created using the CRM Marketing Module can have Planning Tasks associated with it. Sorting for the default view of these Planning Task is on the column Name. For many, it may make more sense to sort this view by Due Date, with those Due in the nearest future (or past) at the top of the list (ascending).

Simple, right? We'll just follow the examples in the Microsoft Team Blog post, and.... Wait a minute! There's no "Planning Tasks" view - anywhere. Now what?

Well after looking through various possibilities, The Planning Tasks view under Campaigns actually uses the "All Tasks" view. Modifications to the All Tasks View will be reflected in your list of Campaign Planning Tasks.

Filed under:
Modifying Additional CRM Views
by Jeremy Hofmann 12.12.08

Comments    No Comments

When you need to modify a view in CRM, nine times out of ten you will modify the view in the Settings | Customization | Customize Entities area of CRM.  Occassionally however, you will find the need to modify additional views that are not available through this area.  Jim Schumacher on the Microsoft Team blog has a great post describing how to access and modify these additional views.  The example is for marketing list members - check it out!

Filed under:
More Posts « Previous page - Next page »