Showing posts with label Plug in. Show all posts
Showing posts with label Plug in. Show all posts

Thursday, April 26, 2012

CRM PlugIn Vs. Client Side Scripting

This is one of the questions which always bothers a CRM developer. If there's a piece of functionality which needs to be developed should I develop it on the client side using JavaScript or should I use a PlugIn to develop it. The answer is it depends :). 

The thumb rule I have is that anything which has business logic or a business rule validation definitely needs to be present in a PlugIn. This ensures that your application is safe independent of the UI which the end user is using.

So what should client side scripting be used for. I believe it should be used for any CRM UI customizations and any validations which you want to perform at the client side.

Validations should avoid the server round trips for performance reasons. So if a validation depends on some data which needs to be pulled from server then I suggest let the PlugIn take care of it. The limitation in this case is that the error box is not very pretty. If you believe that this is not acceptable from the User experience perspective then you should consider embedding some virtual fields in the entity PropertyBag in the Retrieve PlugIn. Pull those dependent fields on the form when the entity is retrieved and then do the validation on the client side.

What if the validation needs to be based on the latest values of fields in another entity? I’ve never come across such a requirement and frankly in web world nothing is really real time. You’ve the server side PlugIn which will redo the validation anyways and if there’s something wrong with the latest value it will throw an error to the user.

So to summarize
1)  Any business logic should always be written in the plug in
2)  Any validation should always be written in a plug in
3)  Any validation that you want to perform on CRM UI should use the javascript API of CRM
4)  Avoid the validations which need a server round trip. Do them only if someone puts a gun on your head J

Njoi!!!

¬Abhishek

Thursday, December 2, 2010

CRM 2011 Beta :- Creating a Workflow Activity to Generate GUIDs

I am working on CRM 2011 Beta and one of the scenarios I have to create a new entity instance from within a process (Previously known as CRM Workflow.). One of the attributes of this entity is a text field which is supposed to store a GUID and hence by definition it should be unique per instance of the entity. 
I couldn't find a way to generate a GUID on the Process designer. This means i have to write a custom activity which would generate a GUID and pass it on to the next step of creating the entity instance. 
In this post i will capture how to create a custom activity. How to register it with CRM 2011 Beta and how to use it in my Process. I will try to attach appropriate snapshots where necessary. 


Before starting to do anything we have to download the CRM 2011 Beta SDK from here. I extracted the SDK in C:\Temp on my machine however it can be extracted anywhere you want to. 
Of course we will need CRM 2011 Beta to be installed on a machine in order to deploy and test the activity from within a process. We will need Visual Studio 2010 to develop the plug in. (This is not a must as you can use utilities from  .NET SDK to build the code however i am going to use Visual Studio 2010 as i have it installed on my box already). 


First we will create an activity using Visual Studio 


1) Create a New Activity Library type of project in Visual Studio 2010. You can find the template in the Workflow section.


2) Delete the Activity1.xaml File as we are not going to use it. 


3) Add a reference to Microsoft.Xrm.Sdk.dll and Microsoft.Xrm.Workflow.dll which can be found in the bin folder inside the folder where you extracted the CRM SDK.


4) After doing this if you compile the project you might get a warning which would say that the above 2 assemblies refer to the Syste.ServiceModel.Web assembly which is not present in the .NET Framework Client Profile target which is defined for the project. Change the target profile of your project to .NET Framework 4. This can be done by going to properties of your Project and changing the Target Framework. 


5) Create a class called GenerateGuidActivity deriving from CodeActivity class inside System.Activities namespace. Make sure that it is a public sealed class. 


6) To add functionality to the activity we need to override Execute(CodeActivityContext context) method. We will come back to the implementation inside this method. 


7) We do not have any input to this process step as it is just supposed to generate a new Guid everytime. So we do not have any input to the activity. However we have to send the Guid as output of the step. So we will just create a property which needs to return this Guid. Since this would be a output parameter for the Activity we would want to define the property as 
    
public OutArgument NewGuid { get; set; }

Note that i have defined argument as type string and not Guid. This is because CRM doesn't understand Guid as output type.


8) In order to ensure that CRM Process designer can understand this as well. We need to decorate the property with an attribute i.e. [Output("NewGuid")]


9) Once this is done we can go ahead and implement the Execute method. That would be simple. Just create a new Guid and set it with the context.   


this.NewGuid.Set(context, Guid.NewGuid().ToString());


10) Build your code and make sure that the activity compiles. 


11) Since the assembly has to be deployed on a CRM Server it would be a good idea to sign it using a key file and give full trust to the key using caspol. 


Now comes the time to deploy this activity to be accessible by CRM Process Designer. To do that we will use the Plugin Registration Tool which ships with CRM 2011 Beta SDK.  You can find the code for tool in SDK\tools\pluginregistration folder. Open the solution, build and run it. 


12) On the home screen Create a New connection using the menu option. Just enter the server name, user name and a friendly name for the connection. 
Press Connect wait for the connection to complete. Once connected the screen would look like the following. 




13) Now click Register menu and Choose "Register New Assembly" Option. 

14) On the dialog box which opens browse and select the assembly which contains the custom activity we built earlier. 

15) Check the Select All checkbox 

16) Leave the other values to be default i.e. Isolation Mode = None , Location Where assembly  has to be stored = "Database"

17) Click Register Selected Plugins. (PS: You might get a dialog saying that there are no plugins to register. The reason for this may be that the Workflow activity you made earlier is not a public class. You might want to change it to a public class to make this work. Another problem which you might face is an error which says "Public assembly must have public key token." This is happening because you forgot to sign your assembly with a key).

18) Once the registration is successful we can go ahead and give a friendly name to this Workflow Activity using the plugin Registration tool. Just enter the name and press Save. Check the figure below for more clarity. 


19) After this you can go and access this custom workflow activity from the Process designer to be used in your process. 

Happy coding... 

~Abhishek

PS :- Pasting the code of the above exercise....



using System.Activities;
using System;
using Microsoft.Xrm.Sdk.Workflow;

namespace Microsoft.Xrm.CustomWorkflowActivity
{
    
    public sealed class GenerateGuidActivity : CodeActivity
    {
        protected override void Execute(CodeActivityContext context)
        {
            this.NewGuid.Set(context, Guid.NewGuid().ToString());
        }

        [Output("NewGuid")]
        public OutArgument NewGuid { get; set; }
    }
}