Saturday, April 26, 2014

CRM 2013 - Refresh and Save functions

In CRM 2013, we have got two different functions one for saving the form and refreshing the form. Advantage of these two are that they are asynchronous in nature which can do the other activities based on the result of this refresh or save. So for example if we need to call function1 if the refresh/save was successful and function2 otherwise its pretty easy now.

We will look at refresh first,
Xrm.Page.data.refresh(save).then(
                function () {
                    //Do something if the refresh is successful
                },
                function () {
                    //Do something if the refresh is unsuccessful
                }
                );
In the above example save is a boolean value which should be used to mention whether we need to save the form after it is refreshed. If true then the form will be saved and if not then the form will not be saved.

Next we will look at the save function.
Xrm.Page.data.save().then(
                function () {
                    //Do something if the save operation is successful.
                },
                function () {
                    //Do something if the save operation is unsuccessful.
                }
                );
In both the above cases the success call back will not have any arguments. It will simply be called if the operation succeeds. At the same time error call back will be having an object with properties:
errorCode: The error code.
message: A localized error message.

One more thing to be noted for these functions are that these two are available only for updated entities.

Hope this helps!!!

Sunday, April 20, 2014

CRM 2013 - Accessing Individual attributes in a composite control

In CRM 2013, the concept of composite attributes is introduced and when the field is used in the form only the composite control will be displayed in the form. When the user has to edit this field the constituent controls will be loaded in the form of flyout controls.

We can get the values of the composite controls using getValue but for setting the value we have to access the individual fields loaded to the form.

These individual forms can be accessed directly. The naming convention followed by such fields are as follows,

<composite control name>_compositionLinkControl_<constituent attribute name>

For example if we have to access address_line1 control in address1_composite use the below code,
Xrm.Page.getControl("address1_composite_compositionLinkControl_address1_line1")

CRM 2013 - Support for tablets

You will be already aware that CRM 2013 support the tablet environment as well. From a developer point of view we need to take care that the code which we are using will also work for the tablet environment. This is because the CRM for tablets does not allow any functions that can block the execution of the scripts. Normal javascript functions like alert, confirm and prompts will not work as we expect in tablets. They will simply throw errors.

If we need to show any message to the user working in tablets then we need to use the latest functions as part of CRM SDK instead of the alerts or prompts. We have to use Xrm.Utility.alertDialog and confirmDialog functions to display messages to the user.This is because these functions do not stop the processing of scripts until the user closes them.

Similarly below are some of the examples that will not work in tablets when using CRM,
  • Xrm.Page.context.getCurrentTheme
  • Xrm.Page.data.entity.getDataXml
  • Xrm.Page.ui.formSelector object methods
  • Xrm.Page.ui.navigation.items collection
  • Xrm.Page.ui.refreshRibbon
  • Xrm.Page.ui.ViewPort methods
  • Xrm.Page.ui.control Webresource and IFRAME control methods
  • Xrm.Page.ui.tab.setDisplayState
  • Xrm.Utility.openWebResource
If opened from the tablets these functions will simply execute an empty function and return nothing. If we expect a return value from these functions it will be undefined.

So if we are customizing in CRM for tablets then its better to distinguish between the code that will run in CRM tablets

It can be done by following below steps,
  1. Get the client type (Xrm.Page.context.client.getClient())
  2. If that is "Mobile" 
  3. Then do the coding for the tablets there
  4. Else do the coding for the normal CRM scenario.
Not only the above fields, CRM for tablets implement the composite fields also in a different way than how the web application implements it. Composite fields will be substituted by the constituent attributes and display them instead.

Similar is the case for Web resources and IFRAMEs. If our code interacts with such objects we can expect that the control will not exist in a tablet CRM environment.

If you are not sure which commands will work on tablets then include a command rule which will not include such commands. 

Wednesday, February 19, 2014

CRM - Adding an activity through code

There can be scenarios where we have to add activities programmatically to the CRM organization either through a plugin or through a workflow. Below is how we can achieve this.
 
Entity followupActivity = new Entity("phonecall");
followupActivity["subject"] = "Followup Phone call activity";
Entity activityPartyFrom = new Entity("activityparty");
activityPartyFrom.Attributes.Add("partyid", new EntityReference("systemuser", workflowContext.UserId));
followupActivity.Attributes.Add("from", new Entity[] { activityPartyFrom });
Entity activityPartyTo = new Entity("activityparty");
activityPartyTo.Attributes.Add("partyid", new EntityReference("lead", "Lead's Guid"));
followupActivity.Attributes.Add("to", new Entity[] { activityPartyTo });
followupActivity["scheduledend"] = DateTime.Now.AddDays(30);
service.Create(followupActivity);
 
 Here I am trying to add a phone call activity and assuming that this is from the workflow, workflowcontext used is the workflow context to get the owner of the activity. I am here trying to add a phone call and the entity should change according to our need. Due date is set to 30 days from today and the from is the user under which the workflow is running and to is a lead whose Guid we need to pass so as to set the To field.
 
Hope this helps !!!

Monday, February 17, 2014

CRM - Passing data between Plugins

When working with Plugins its quite natural to come across the scenarios where a data needs to be shared by two different plugins. This can be achieved using the shared variables. Below is how it can be done. In the plugin which is going to set the variable write the code as follows,
 
context.SharedVariables["UniqueName"] = "Data to be shared";
 
context is the plugin execution context. Now the data that needs to be shared is available in the shared variable UniqueName.
 
Next step is to consume the data available in the other plugin. For that first check whether the shared variable has the respective UniqueName. If available consume the data in it using the below code.
 
string uniqueName = (string)context.SharedVariables["PrimaryContact"];
 
All done. We have the data from first plugin in second one now. Enjoy !!!

Monday, February 10, 2014

WPF - Supressing Script Errors in WPF WebBrowser control

When Web sites hosted in Webbrowser controls are throwing JScript errors then we have to hide them. WebBrowser controls don't have the property to hide script errors so we have to handle it explicitly or we have to use WinForms WebBrowser control.
 
For the first approach we can use the below method in the browsers navigated event.

private void HideScriptErrors(WebBrowser webBrowser, bool hide)
{FieldInfo fieldInfo = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);
if (fieldInfo == null)
return;
object objectWebBrowser = fieldInfo.GetValue(webBrowser);
if (objectWebBrowser == null)
return;
objectWebBrowser.GetType().InvokeMember("silent", BindingFlags.SetProperty, null, objectWebBrowser, new object[] { hide });
}

You can look at the original post here.

This worked for me. Hope it will for you as well !!! :)

Thursday, February 6, 2014

CRM 2013 - Create a SDK code project in Visual Studio

As a developer, there can be scenarios where we have to use CRM SDK in our code so as to connect to CRM and use the messages from SDK. To make sure our VS project is ready to use we have to follow some steps.

Even though the title says 2013 this is applicable to 2011 as well.
 

Prerequisites

Below are the prerequisites for the same.
  • Any Visual Studio (even the express edition works): CRM SDK is built on .NET 4.0 so even VS 2010 will work in this case.
  • CRM SDK: If CRM SDK is not installed on your computer, it can be downloaded from here (CRM 2011, CRM 2013).
  • Windows Identity Foundation: If you are using windows 8 or Windows server 2012, then we have to just enable already existing WIF. If you are using windows 7 or windows server 2008, we have install the WIF 3.5. For installing, download it from here.
 Once all the prerequisites are in place we can start creating a project which will interact with CRM from our code. Follow the below steps for achieving our target,
  1. Create a console application for either C# or VB according to our comfort level.
  2. Make sure the target framework is set to MS .NET framework 4.0. By default it will be client profile.
  3. Add all the required reference to our project. This includes below references.
    1. System.Data.Linq
    2. System.DirectoryServices.AccountManagement
    3. System.Runtime.Serialization
    4. System.Security
    5. System.ServiceModel
  4. Add the required SDK assembly reference as per our requirement. This is available from the bin folder of respective CRM version SDK.
  5. Add the required identity reference file. We can get this file from the file location in the system at Program Files\Reference Assemblies\Microsoft\Windows Identity Foundation\v3.5.
We are done with adding the references and now we are ready to go with our development activity.
 
For every project we have to do this. So its better if we can save this as a project template for our future references.
 
For detailed Microsoft documentation please refer the original site here.
Hope this helped everyone. :) !!!
 
 

Configuration for CRM Plugins

CRM plugins are always great feature where we can automate many functionality which we cannot automate from user interface. But almost eve...