This is a blog about my experiences with Microsoft Dynamics CRM, tips and tricks as well as news from the CRM community.
Wednesday, August 29, 2012
CRM 2011: Plug-in assembly does not contain the required types or assembly content cannot be updated
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
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:
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?
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)
|