Microsoft Dynamics CRM 2011

Microsoft Dynamics CRM 2011
Showing posts with label Workflows. Show all posts
Showing posts with label Workflows. Show all posts

Tuesday, April 21, 2015

How to use Tracing in CRM 2011-2013 Plugins and Workflows

In this article we describe Step by step How to use Tracing in CRM 2011-2013 Plugins and Workflows in C# in 5 minutes.
Since CRM Plugins and Workflows are deployed on web servers after the development reaches the release stage , it is usually very helpful to include tracing in your code in profusion, not only in error cases, at least when you are putting to the test new developments .
CRM 2011-2013 allows you to include tracing galore:
How to use Tracing in CRM 2011-2013 Plugins and Workflows



How to use Tracing in CRM 2011-2013 Plugins and Workflows



Phase 1: use the GetExtension() method from the "context" at your plugin-workflow:
Tracing in CRM 2011-2013 Plugins and Workflows


Since this is a generic C# Dot.Net method, use the ITracingService interface to get the tracing service from the context.


Phase 2: Send the ITracingService to any method where you intend to log information using tracing:

CRM 2011-2013 Plugins and Workflows

For example:

How to use Tracing in CRM


Phase 3: inside the plugin's methods, call the ITracingService's Trace() method to send messages to the tracing:

How to use Tracing in CRM 2011-2013


In case of error, CRM will display an alert showing the tracing:


How to use Tracing in CRM 2011-2013 Plugins and Workflows


That's all...Enjoy Dynamics CRM

by Carmel Schvartzman

כתב: כרמל שוורצמן


    Wednesday, April 15, 2015

    How to programmatically create a CustomerAddress in Dynamics CRM 2011/2013


    1. In this article we see how to programmatically create a CustomerAddress in Dynamics CRM 2011/2013. 
      In CRM 2013, the address data of an Account or a Contact are stored in a separate Entity called CustomerAddress, on a 1:N relationship basis, in which an Account can have (and have, by default) many addresses.
      This post is about Dynamics CRM 2011 - 2013 custom Plugins or custom Workflows, and any   C# code which calls the CRM Organization Web Service to create a new CustomerAddress item , that means, a third address for an Account or a Contact. The following snapshot shows the Account address fields:
      How to programmatically create a CustomerAddress in Dynamics CRM 2011/2013

    How to programmatically create a CustomerAddress in Dynamics CRM 2011/2013


    1. When an Account is created, CRM creates by default 2 addresses for it, from  the CustomerAddress entity type, which are called Address1 and Address2.
    2. If you intend to programmatically update the Account or Contact address, and not to create a new address, you just instantiate the following Account fields with the data, and CRM will automatically update the corresponding CustomerAddresses objects related to the specific Account:
    oAccount["address1_telephone1"]
    oAccount["address1_line1"]oAccount["address1_city"]oAccount["address1_postalcode"]


    Change "Address1" with "Address2" if you want to update the second Account address.

    If you intend to create a new (third) CustomerAddress item for the Account, follow this step by step instructions:

    1. First we write a check to see whether we got a legal ID of the Account we want to refer to:

      if (guidParentAccount.HasValue){
    2. Then we create the CustomerAddress entity , and instantiate the "ParentID" of the CustomerAddress . When creating a new address for an Account or a Contact entity, it's crucial to provide a reference field which points to the "ParentId" , that means , the Account or Contact to which belongs this new address. The C# code below instantiates the "ParentId" property with the actual Account , and not just the Parent's  ID (guid) :

      Entity oAccountAddress = new Entity("customeraddress");                                  
      EntityReference parentID = new EntityReference();                   
      parentID.Id = guidParentAccount.Value;                   
      parentID.LogicalName = "account";
                         
       oAccountAddress.Attributes["parentid"] = parentID;
    3. However, if you try to instantiate this "ParentId" field with the guid, you will be confronted with an exception , that's raised informing that the value is null : this error message is misleading, and we wrote about it in another article here.
    4. Another way, shorter, to instantiate the ParentID is the following:

      oAccountAddress["parentid"] = new EntityReference("account", guidParentAccount.Value );
    5. Next we save the street in the "line1" field: for the example, here i made a street search by street code on a generic List<> which contains street codes and descriptions:
                      

        string sStreetDescription = String.Empty;                   
        if ( oStreetList != null &&  oStreetList.Count > 0  && iStreetCode > 0)                   
        {                       
                 sStreetDescription = oStreetList.FirstOrDefault(sc => sc.Code == iStreetCode).Description;                       
                 if (sStreetDescription.Length > 0)                       
                 {                           
                           oAccountAddress["line1"] = sStreetDescription;                       
                 }                   
        }
    6. Next we save the city  in the "city" field: for this example, here i got a city object also from data migration, which contains both city code and description:

      string sCityDescription = String.Empty;                   
      if (oCity != null)                   
      {                       
            sCityDescription = oCity.Description;                       
            if (sCityDescription.Length > 0)                       
            {                           
                     oAccountAddress["city"] = sCityDescription;                       
            }                   
      }


    7. Then we instantiate the "postalcode" and "telephone1" properties:

       if (oAccount.Zip != null)                    
      {                        
               oAccountAddress["postalcode"] = Convert.ToString(oAccount.Zip);                    
      }
      oAccountAddress["telephone1"] = oAccount.Phone ?? "0";
    8. Finally we call the Organization Web Service to create the CustomerAddress entity from the Account:

      Guid? guidAccountAddress = XrmContext.Create(oAccountAddress);
    9. The CRM database will then reflect the 3 addresses (AddressNumber 1,2 and 3) as shown here:
      How to programmatically create a CustomerAddress in Dynamics CRM 2011/20131
       


    That's all...Enjoy Dynamics CRM!!!

    by Carmel Schvartzman

    כתב: כרמל שוורצמן

      Monday, June 30, 2014

      PlugIns - How to create the CRM Organization Service in a CRM 2013 C# Workflow

      by Carmel Schvartzman
      1. This is the Building Block C# code  to create the CRM Organization Service in a CRM 2013 Workflow.
      2. The present code relates to a custom  Plugin / Workflow in Dynamics CRM 2011/2013. Once you have developed your custom workflow, you deploy the assembly containing the plugin in the CRM web server, and register it with the Plugin Registration Tool of the CRM 2011 SDK.
      3. Then you use this code to set up the Xrm Organization Service that you need to interact with the CRM organization:
      protected override void Execute(CodeActivityContext context)
              {
                  #region GET THE EXECUTION CONTEXT FROM THE SERVICE PROVIDER VARIABLE :
                  execContext = context.GetExtension<IExecutionContext>();
                  workflowContext =
                      context.GetExtension<IWorkflowContext>();
                  serviceFactory =
                      context.GetExtension<IOrganizationServiceFactory>();
                  service =
                      serviceFactory.CreateOrganizationService(workflowContext.UserId);
                           
                  ITracingService tracingService = context.GetExtension<ITracingService>();
                 #endregion
                  ///////////////////////////////////////////////////////////////////////////////////////////
                  // Business Logic:
                  ExecuteYourBussinessLogicMethod(context, workflowContext, tracingService);
                  //////////////////////////////////////////////////////////////////////////////////////////
              }

                                                      That's all...Enjoy Dynamics CRM 2013


                                                      כתב: כרמל שוורצמן

                                                      Wednesday, April 30, 2014

                                                      "The given key was not present in the dictionary" KeyNotFoundException Exception in CRM 2013 Plugin or custom Workflow

                                                      by Carmel Shvartzman

                                                      In this walkthrough we will learn how to take care of the "The given key was not present in the dictionary" - "KeyNotFoundException" error in a Dynamics CRM 2013 (2011) Plug-in or custom Workflow.
                                                      1. A disadvantage of using late-binding when coding a CRM 2013 Plugin is, you shoud be very careful with the attributes names, since there is no compile time checking. 
                                                      2. Specially when you have added a new field to an entity, and you get the "The given key was not present in the dictionary" Exception, you'll be prone to think something is not good with the new field definitions, or worse , the Organization Web Service is not recognizing the new field, or even worse, the Web Service needs to be reset to render the field, or may be you'd be desperately thinking to restart the CRM server to refresh the Web Service.
                                                      3. That's because the error message by CRM may be misleading : you may be expecting that, in case your new field contains a null value, CRM Retrieve() or RetrieveMultiple() or Execute() will locate the field attribute, and fetch a NULL value for it. But CRM wouldn't : it WILL NOT INCLUDE THE KEY IN THE ATTRIBUTE'S DICTIONARY UNLESS IT CONTAINS A VALUE : if your field is not a REQUIRED field, you must code a checking for the presence or absence of the field.
                                                      4. For instance, let's say you've added a new field named "new_test", and inside your Plug In you fetch it as follows:
                                                      5. If the present entity has a NULL value in it , you'll be faced to the "The given Key..." exception:
                                                      6. First think you'll want to check, is whether you requested for the field in the ColumnsSet:
                                                      7. But that's not the problem. You did indeed. However, the "new_test" field attribute IS NOT THERE:

                                                      8. That's because CRM WILL NOT INCLUDE THE KEY IN THE ATTRIBUTE'S DICTIONARY UNLESS IT CONTAINS A VALUE (meaning it was SET or UPDATED).
                                                      9. You MUST perform a check for the field existence, but not a NULL check as this:
                                                      10. You should instead use the ContainsKey(string) method from the Collection, for EVERY NO REQUIRED FIELD on the Entity:



                                                        Hoping it helped you.
                                                        That's all...Enjoy Dynamics CRM


                                                        כתב: כרמל שוורצמן

                                                      Tuesday, December 24, 2013

                                                      How to debug a CRM 2011 Custom Plugin / Workflow

                                                      by Carmel Schvartzman

                                                      1. In this walkthrough we will learn Step - By - Step How to debug a custom  Plugin / Workflow in Dynamics CRM 2011. Once you have developed your custom workflow, you deploy the assembly containing the plugin in the CRM web server, and register it with the Plugin Registration Tool of the CRM 2011 SDK.
                                                      2. The problem is, every time you change the code, and recompile the assembly, you must redeploy it and the process of debugging-compiling-deploying-registering is very time-consumer and this cycle restarts for every bug and every update you may want to do.
                                                      3. The best and quickest way of debugging-redeploying  your plugin is inside the CRM server itself. If you upgrade your code from inside the CRM web server, the process of debug and redeploy it will be far more quicker. You can also perform the testings against a test Organization.
                                                      4. First, check whether or not Visual Studio 2010-2012 is installed in the CRM web server. If it doesn't, install it.
                                                      5. Next, copy the workflow solution to the CRM server, or else develop entirely your  Plugin from the Visual Studio in the CRM server.
                                                      6. Provided you have already built your workflow project, you must deploy it in the CRM server. You copy the assembly from the BIN folder of your project, to the special folder where CRM expects the plugins to be ( Microsoft Dynamics Crm\Server\Bin\Assemply ). Then, open the Plugin Registration Tool, and select "Register New Assembly":
                                                      7. How to debug a CRM 2011 Custom Plugin / Workflow
                                                      8. Specify the assembly location:
                                                      9. Select the "Database" option:
                                                      10. Now that your plugin has been registered, you can debug it this way: switch to the workflow project opened in the Visual Studio installed on the CRM web server:
                                                      11. On the "Debug" tab, select "Attach to Process":
                                                      12. Now select the two "CrmAsynchService.exe" which are running on the CRM server. Those are the services which take care of the plugins, workflows, and every asynchronic processes being run on the CRM 2011:
                                                      13. Press the "Attach" for each one of the processes:
                                                      14. Now debug your workflow at your ease. Open your CRM account and call the workflow which calls your custom plugin/workflow. Wait some seconds (it's an asynchronic process so CRM will decide by its own when to run your plugin) and you'll see that the breakpoints you have set on your code will be reached.
                                                      15. Let's say that you've found a bug or you need to upgrade the code. You compile it and next you must redeploy the assembly and update the registration of the plugin, and debug again.  Therefore, open the BIN folder of your workflow project, and copy the .dll:
                                                      16. Now open the folder where are stored the CRM custom plugins ( Microsoft Dynamics Crm\Server\Bin\Assemply ):
                                                      17. Paste there the assembly. Next, open the Plugin Registration Tool, select your assembly and press "Update":
                                                      18. Specify the location of the assembly to update:
                                                      19. Finally click the button "Update Selected Plugins":



                                                        And now you can debug again your plugin and see how the breakpoints are reached by the runtime.


                                                        That's all...Enjoy Dynamics CRM


                                                        כתב: כרמל שוורצמן

                                                      Monday, October 14, 2013

                                                      Step-By-Step How to create a Dialog in CRM 2011


                                                      by Carmel Schvartzman

                                                      1. In this walkthrough we will learn How to create a Dialog  in Dynamics CRM 2011. A CRM 2011 Dialog can automate processes, force bussiness rules,  and even guide the users through everyday tasks. 
                                                      2. We'll automate a part of the creation of a new Contact, using a custom Dialog. 
                                                      3. Suppose in our firm we want a new Contact belonging to certain Customer, to have not just a Bussiness phone, but also we need it to include a Mobile and Home numbers.
                                                      4. In order to attain that, we'll create a Dialog which will lead the user to save a new Contact fast and comfortably, but constraining to type those phone numbers . If they're not typed, we will CRM to copy the Bussiness phone number to both Mobile and Home fields.
                                                      5. Let's state that the Contacts whose Parent Customer is "Rick Deckard", will be required to state not only bussiness phone number, but also their Mobile and Home phones.
                                                      6. In Customize the System, go to Processes:
                                                      7. And Create a new Process:

                                                      8. The Entity will  be Contact, and the Category "Dialog":

                                                      9. State that the Dialog will run On Demand, and Add a new Step:

                                                      10. The step will Check a CONDITION:
                                                      11. On the dialog that opens, select "Parent Customer":

                                                      12. The "account" property of the Parent Customer, meaning the Account object...

                                                      13. ... must equal...

                                                      14. ...the "Rick Deckard" Account:

                                                      15. Check that you established the correct conditions:

                                                      16. Next, IF this condition is TRUE, we want a Page to open (is important that you click and focus the correct AREA beneath the condition, to include this step UNDER THE SCOPE of the former step, and not as a step per se):
                                                      17. Enter a description for the step:


                                                        And under the scope of THIS Page, add a new "Prompt and Response" step:
                                                      18. The Page will prompt to the user to enter both Mobile and Home phone numbers:


                                                      19. Now, we'll add a checking to see whether the user did that:

                                                      20. The CONDITION will use the current Contact entity:
                                                      21. ...and its "Mobile Phone" field:

                                                      22. ...and will check whether it contains data:

                                                      23. This is the CONDITION ready to be saved:

                                                      24. Inside the scope of this condition, we'll add a new Page containing a Prompt:
                                                      25. The prompt will state to the user that because she/he didn't enter the numbers, therefore CRM proceeds to clone the Bussiness number:
                                                      26. Next, and again inside the SCOPE OF THE CONDITION, we need to UPDATE our Contact to copy the numbers: so add a step to Update the Record:
                                                      27. In the Contact form that opens, click on the "Home Phone" to focus:
                                                      28. And select the Business Phone" from the Contact on the Form Assistant:
                                                      29. You'll see that the Business Phone will be attached to the "Home Phone" field:

                                                      30. Do exactly the same for the "Mobile Phone" field:
                                                      31. Next, close and take a look at the final cut of the Dialog:
                                                      32. Now Save and ACTIVATE the dialog:

                                                      33. Now let's see how it works. Create a New Contact and enter some data in it. Remember to set the Parent Customer to "Rick Deckard", in order to fulfill the first CONDITION of the dialog:

                                                      34. For the first test, let's see what happens if the user typed indeed the three phone numbers:
                                                      35. Start the Dialog:
                                                      36. ... selecting the dialog we created:

                                                      37. ...and you'll see the first prompt appearing:

                                                      38. ... and the "Next" leads the user right to the end of the dialog:

                                                        Why is that? Because the user typed the three phone numbers, and the second condition doesn't apply.
                                                      39. Now let's do the test without the phone numbers:
                                                      40. The first prompt fires:
                                                      41. But the user hasn't got the numbers, therefore the second IF condition applies:
                                                      42. Save and close the Contact:
                                                      43. ..and when reopening it, you'll see the phone values had been copied automatically by CRM 2011:







                                                        That's all...Enjoy Dynamics CRM



                                                        כתב: כרמל שוורצמן