Wednesday, August 29, 2012

CRM 2011: Plug-in assembly does not contain the required types or assembly content cannot be updated

This post explains why you receive this error message when trying to update a plugin assembly in CRM 2011 and how to correct it.
This is another very popular question in the community, why do I get the following error message when updating a plugin assembly?
Plug-in assembly does not contain the required types or assembly content cannot be updated (Error Code -2147204725)
The answer is not very simple as there are a number of conditions that would produce that error message, and these conditions are barely covered in the official documentation from Microsoft. So here are the things you need to check:

1. You are not allowed to update the assembly metadata (strong name)
The new plugin assembly must have the same fully qualified name (same culture, publickeytoken, name and version). You are allowed (and should!) modify the version build and/or revision number but you cannot change the major or minor version. Your assembly version is always in the form <major.minor.build.revision> and you can specify the assembly version in Visual Studio before you build. Note that because the publickeytoken must be the same, then you must use the same key to sign your assembly as you used for the original assembly you are trying to replace.

2. You cannot remove or rename classes which are already registered as plugin types
A plugin type is basically a class which implements IPlugin and they might or might not be registered in CRM as plugins. If your plugin assembly has any plugin types registered under it, then you need to make sure that your new assembly contains those registered types with the same class names. It is important that the signature of each class which is registered as a plugin is not changed in your new assembly (internal and helper classes can always change with no problem, but not the public plugin classes). If you wish to change the class name of a registered plugin (for example you had a plugin called "MyPlugin" and then you changed the name of a class to "MyNewPlugin") you will have to first unregister that plugin type and then you can successfully update the plugin assembly which contains new plugin type and then you’d have to re-register the new plugin type.

3. You cannot change or remove arguments of custom workflow activities
If your plugin assembly contains custom workflow activities which are registered and which have In or Out arguments, then you are not allowed to update the assembly if you are making changes to the custom workflow activity arguments. Removing or changing the datatype or the name of the arguments is not allowed; however, adding new arguments is OK (not recommended though). If you would like to change the arguments then you’d have to unregister the custom workflow activity from the system, update the new assembly and then re-register the custom workflow activity with the updated arguments. You can find more details about how workflows behave with different version of the plugin assembly: http://gonzaloruizcrm.blogspot.ca/2011/08/assembly-versioning-in-crm-2011.html

If you absolutely need to make a change which is not allowed in the list above, then you would need to either unregister the old assembly and re-register everything back or you can increase the major/minor version of your assembly and then register it as a new assembly (but you cannot update the existing one). Also keep in mind that in general it is a good practice to always change the build/revision number before you update an assembly. That way, the new assembly will be used immediately without having to run iisreset or restart CRM services.
If you find other conditions that cause this error message you can comment on this post. Also, I

Monday, August 20, 2012

Learn About The Microsoft Private Cloud to Win a Trip for Two to Mexico!

Microsoft has released new and exciting products that will change the way IT Pros utilize Virtualization and Microsoft Private Cloud solutions.   Two products which are a part of these great changes are the newly released System Center 2012 and the soon to be released Windows Server 2012.  Both of these solutions were designed to make virtualization and extending to the private cloud simpler and much more efficient. 

With these new changes to Infrastructure and the IT world, it’s a great time to learn about these new solutions and keep yourself and your organization ahead of the curve in terms of where technology is headed.  In fact, Microsoft has even added an incentive to learn about their Private Cloud solutions through the Skyrocket Sweepstakes! 

Entering is easy!  All you have to do is register, and then download a free TechNet evaluation like Windows Server 2012 RC or System Center 2012 to get started.  Every applicable evaluation you download gives you an entry into the sweepstakes! And the best part is the more evaluations you download, the better your chances.  And what’s the prize you may ask? Oh, just a 7 day, 8 night trip for two to Cozumel, Mexico!

The contest ends September 6th so don’t wait!  Register now!

Workflow Persistence in CRM 2011

Commonly disregarded during workflow design, persistence is critical to understand in some scenarios in which it affects the logic of the workflows in CRM. This post explains how workflow execution is affected by persistence.

I think the best way to explain this topic is in “FAQ” format:


1. What is persistence?

Persistence (in this context) means taking a snapshot of the state of a workflow job and storing it in the database. This is similar to clicking the “Save” button when you are writing a Word document. Persistence is a common term in WF (Windows Workflow Foundation) on which CRM workflow is based. The “snapshot” of the workflow job is serialized and stored in the Async Operation table.


2. When are workflows persisted?

CRM will automatically persist workflow jobs right after successfully completing any of these Out-of-the-Box workflow steps:


  • Assign Record

  • Start Child Workflow

  • Create Record

  • Send E-mail

  • Change Status

  • Stage

  • Update Record

Additionally, whenever the workflow goes into a “waiting” status (not due to an error), it will persist to database.


3. In what cases does this matter?

When a workflow is suspended due to a recoverable error, the user is allowed to manually resume the workflow. But when you click “Resume”, from what step is it going to resume? This depends on the last time that the job was persisted. In some cases, you might end up re-executing some steps because your workflow job did not persist after each step. For example, consider this workflow:

1. Create a record (CRM automatically persists after a successful Create step)

2. Custom activity to create the record in an external system

3. Send email to the record owner to notify that the record has been created in CRM and in the external system. (CRM automatically persists after a successful Send E-mail step)

Now imagine that the new record owner did not have a valid email address in CRM. In this case, the job will be suspended and you will need to enter the email address in the user record and then resume the workflow:

image

Note that the last persistence point is after the create step (because custom activity steps are not persisted). Therefore, when you resume the workflow, it will resume from the beginning of step 2. Thus your workflow will end up executing step 2 twice and you end up with a duplicate in the external system. I hope this example helps illustrate why persistence does matter and can affect the workflow behaviour when resuming suspended jobs.


4. So how can I control persistence?

It is very limited the amount of control you have on persistence. For example, you cannot prevent CRM from automatically persisting the workflow job for the scenarios described above. However, there are some tricks to force CRM to persist the job where it usually wouldn’t. In the example above, I would have liked to persist the workflow job after step2 completed successfully. In order to do that I could have easily used stages so if my custom activity is inside its own Stage then it will be persisted, because CRM will always persist after a stage is successfully completed.

This workaround (using stages) works most of the times, however stage steps cannot be nested and in some scenarios you want to persist a step that is nested inside another one (for example a custom activity inside a condition branch). Unfortunately, there is not much else you can do to force your custom workflow activity to persist the job upon successful completion. Stay tuned for the CRM2011WorkflowUtilities as I will soon provide a “Persist” custom workflow activity which you can use in your workflows.




5. What about the old PersistOnClose attribute?

In WWF3.5 (CRM 4.0) you could add the [PersistOnClose] attribute to your custom workflow activity (System.Workflow.ComponentModel.SequenceActivity) to force CRM to persist when your custom workflow activity is finished executing. For back-wards compatibility, this is still the case in CRM 2011. However, if you build new custom workflow activities for CRM 2011 you should use WF4 (System.Activities.CodeActivity) which does not support the [PersistOnClose] attribute. In short, if you have CRM 4.0 custom workflow activities they will continue to work in CRM 2011 and the [PersistOnClose] functionality will also work, but you should think about upgrading them to WF4.




6. What about the WF4 “Persist” activity (System.Activities.Statements.Persist)

This Out-of-the-box activity that is included in the WF4 activity palette forces the workflow host to persist. Unfortunately, you cannot use this activity in CRM unless you design your workflows in the WF4 designer and upload them as XAML workflows in CRM (which is not supported in CRM Online). Stay tuned for the CRM2011WorkflowUtilities as I will soon provide a similar “Persist” custom workflow activity which you can use in your workflows in the CRM process designer.

Monday, August 13, 2012

Custom Entity or Custom Activity in CRM 2011?

Not sure if you need a custom activity or a custom entity? This post mostly written by my co-worker Patrick Vantillard includes some of his conclusions after making some research about when to use a custom entity vs. a custom activity.


Difference
Custom Activity
Custom Entity
Logically
An activity represents an action such as making a call, or attending a meeting. This typically involves completing some “work” which is associated with the duration field (how long did it take you to complete the activity).
Activities typically have a lifecycle: opened à assigned à worked on à closed.
Activities in general cannot have sub-activities, at least not in the same native way that entities have associated activities.
Custom entities can represent any business entity. Custom entities store master data or transactional data and can have activities associated with the custom entity record.
Security
Given a security role, the same security applies to all activities (standard & custom) at once. You cannot give a different access level or privilege for a specific activity. For example, you cannot restrict “Delete” access to your custom activity but grant “Delete” access to other activities like Task.
You can control security privileges for each custom entity separately.
Visibility in the Application
When creating a custom activity you can check the “Display in Activity Menu” option which if selected, the custom activity will appear in all the Activity menus as well as the ribbon of all the activity-able entities (of course the ribbon can always be modified after).
We can hide custom activities in the activity menus by unchecking the “Display in Activity Menu” box. NOTE: once the activity is created, that setting cannot be modified.
By hiding the custom activity from the Activity Menu, your custom activities will also NOT show up in the “Activities” or “Closed Activities” views and associated views, so you would need a separate view for your custom activity (as if it were a custom entity).
Visibility of custom entities is controlled by the sitemap and form navigation menus.

Associating to the Case Entity
Because Case is an activity-able entity then your custom activity can be associated with a Case without the need of any special custom relationship and you can re-use the “Activities” and “Closed Activities” navigation menu to show all activities including your custom activity.
Custom entities will require a custom relationship to be able to associate them to a case. Therefore, you would require a new section in the form navigation to show specifically your associated custom entities.
Resolving a Case
By default, the case has been built in order to not allow a user to resolve a case as long as any of the related activities (standard & custom) are still open.
There is no validation on the status of the related custom entities when resolving a case.
Calculation of Time Spent on a Case
By default, on completion of the case, the Total time of the case will be calculated from the sum of duration values for associated activities.
When a case is reactivated and then resolved again, Total Time field is calculated with two different options:
1. If no contract associated with case, time spent on additional activities added to original total, included in Total Time.
2. If contract associated with case, only time spent on additional activities included in Total Time.
Associated custom entities have no effect on the calculated Total Time Spent on the case.
Contracts Related to Case
While creating a contract, a user can select an Allotment Type. A user can therefore specify how the support will be “budgeted” (or, “allotted”) for a contract. You can specify number of incidents, or amount of time (linked to activities)
On the contrary, no such behavior has been created on the contract level linked to standard and custom entities.
Dashboards, Charts and Views
By default, will be able to create a single chart comparing different type of standard and custom activities. Since all activities roll up to the “Activity” (activitypointer) base entity, you can create a chart/dashboard/view which takes data from all activity types including your custom activities.
The system won’t allow a user to create a single chart comparing multiple standard or custom entities. One chart will be required by entity.
Extensions in Silverlight or SSRS would be required to combine data from multiple entities.
Reports
Some out of the box reports are available will automatically include your custom activity. In addition, the report wizard will allow the user to create very easily some reports comparing all related activities linked to a case on a single Report
No reports are available out of the box for custom entities linked to a case.

In addition, the report wizard could be used by the user but the user won’t be able to combine multiple custom entities linked to a specific case. Thus, there is no simple way to provide an overview of a specific case and its related entities. ( e.g. Case linked to two custom entities: Main entity and a Peer Review)