Friday, June 4, 2021

Dynamics 365 C# plugin code snippet for different data type fields

Dynamics 365 plugin & C# common code snippet with different data type fields 

In this blog I'm going to write general or re-usable common C# code for plugin to get and set the value of different data type fields and frequently used code :
Here we go:

1. List of most common namespaces which we use frequently while writing plugin code:

using System;
using System.Configuration;
using System.ServiceModel;
// These namespaces are found in the Microsoft.Crm.Sdk.Proxy.dll assembly
using Microsoft.Crm.Sdk.Messages;
// These namespaces are found in the Microsoft.Xrm.Sdk.dll assembly
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Tooling.Connector;
// These namespaces are found in the Microsoft.Xrm.Client.dll assembly
using System.Collections.Generic;
 
// These namespaces are located in the SDK\bin folder of the SDK download.


2. Code to connect to CRM organisation:

String userName = "";
        String userPassword = "";
        String userDomain = "";
        String crmServer = "";
        String crmPort = ";";
        String crmOrg = "";
        String homeRealm = "";
        NetworkCredential netCred =
            new System.Net.NetworkCredential(userName, userPassword, userDomain, homeRealm);
        CrmServiceClient crmSvc =

            new CrmServiceClient(netCred, crmServer, crmPort, crmOrg);

3. Derive Context, CRM Service object in plugin C#:


IPluginExecutionContext context =
(IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
        IOrganizationServiceFactory serviceFactory =
        (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
        IOrganizationService Service =

        ServiceFactory.CreateOrganizationService(context.UserId);

4. Validate if a specific attribute present in the plugin context input parameter C#:

if (context.InputParameters.Contains("Target") &&  Context.InputParameters["Target"] is Entity)
{
 //Your code goes here

}

5. Check if a specific attribute present in a entity C#

if (entityObject.Attributes.ContainsKey("")
{
//Your code goes here

}

6. Get Value of attribute from entity C#

  • Lookup GUID:

entityObject.GetAttributeValue<EntityReference>("LookupField_SchemaName").Id;

  • DateTime:

//The below code will only give date value

        entityObject.GetAttributeValue<DateTime>("DateField_SchemaName").ToShortDateString();

//The below code will give the Date and Time value

        entityObject.GetAttributeValue<DateTime>("DateField_SchemaName").ToString();

  • String || Single Line || Multi Line:

//SingleLine of text || MultiLine of text

        entityObject.GetAttributeValue<string>("StringField_SchemaName");

  • Boolean || bool :


entityObject.GetAttributeValue<
bool>("BooleanField_SchemaName");

  • Option Set:

//To get options from the option set field

        entityObject.GetAttributeValue<OptionSetValue>("OptionSetField_SchemaName").Value;


7. Retrieve Optionset Value from an AliasedValue (C#)

AliasedValue aliasedval = entityObject.GetAttributeValue<OptionSetValue>("OptionSetField_SchemaName").Value;

int optionSetVal = ((OptionSetValue)aliasedval).Value;

//NOTE: for other datatypes just use the datatype in above line of code to get the value.

8. Code to stop Plugin from infinite loop (C#)

// add this code before your actual plugin logic starts

if (context.Depth > 1)

return;

9. Code to use Shared Variable in Plugins (C#) 

//Get the Shared Variable Value
 Guid contact = new Guid((string)context.SharedVariables["PrimaryContact"]);
//Set the shared variable Value

context.SharedVariables.Add("PrimaryContactbject", (Object)contact.ToString());

9. Get the Pre & Post Entity Images in Plugin (C#)

Entity preEntityImage = context.PreEntityImages["ImageName"];
Entity postEntityImage = context.PostEntityImages["ImageName"];

//NOTE : The Image Names are defined in Plugin registration tool against the SDK steps.

10. Trace Messages using Tracing service in Plugin (C#)

ITracingService tracingService =(ITracingService)serviceProvider.GetService(typeof(ITracingService));

tracingService.Trace("Pass trace message here");


11. Retrieve entity record data using Query Expression(C#)

//Query for the GUID of the Account using Account Name
QueryExpression query = new QueryExpression("account");
string[] cols = { "accountid", "name" };
query.Criteria = new FilterExpression();
query.Criteria.AddCondition("name", ConditionOperator.Equal);
query.ColumnSet = new ColumnSet(cols);
EntityCollection account = service.RetrieveMultiple(query);

//Casting the reference to GUID
Guid accountId = (Guid)account[0].Attributes["accountid"];

12. Retrieve entity record data using Fetch XML(C#)

string fetchxml = @" Add your fetch xml code here";

EntityCollection result = service.RetrieveMultiple(new FetchExpression(fetchxml));

13. Retrieve entity record data using Guid of the record(C#)

ColumnSet cs = new ColumnSet("attribute1", "attribute2");

Entity result = service.Retrieve("", new Guid(""), cs);

14. Create Retrieve Update Delete Entity Record (C#)

Create record: 

    To create a record, you first need to create your entity object. Provide the entity schema name, and add any attributes you want to set.
You then simply call the create function on your service. The create function takes a single parameter of the entity. It returns the record id of the newly created record. The entity object you passed as an argument will not have its id automatically populated.

Entity contact = new Entity("contact");
contact["firstname"] = "Soniya";
contact["lastname"] = "Sharma";

Guid contactId = service.Create(contact);

If you need to create a set of related records, you just need to create them in order of child to parent. Using the first record id as an argument in an entity reference.

Entity account = new Entity("account");
account["name"] = "Soniya Account";
account["primarycontactid"] = new EntityReference("contact", contactId);

service.Create(account);


Retrieve record:

    There are two types of retrieve in 365. Retrieving a single record; which you can only do when you already know the record id. Retrieving multiple records using a search condition. In this article, I’ll be looking at a simple retrieve.

Provide the schema name of the entity you want to retrieve, the record id, and a column set. The column set specifies the columns you want to retrieve for the record. This will return an entity object, it’s always populated with a couple of extra fields beyond your column set, namely the record id. You can then retrieve values from the entities' attribute collection.

Entity contact = service.Retrieve("contact", contactId, new ColumnSet("lastname", "middlename"));
 

return contact.GetAttributeValue<string>("lastname");

If you are feeling extravagant, you can use an alternative column set constructor which takes a bool. Setting true will cause 365 to return all attributes for that record. This is often considered bad practice as you will be causing 365 to load more data from SQL than you actually require.

new ColumnSet(true)

Only attributes that are populated in 365 will be returned in an entities attributes collection. This is the hazard in using the entity attribute indexer, missing keys due to null data in CRM will result in exceptions. Use the GetAttributeValue function instead, missing keys will then be returned as null for classes, or for structs the default value.

contact["middlename"]; //middle name is not populated in 365. //Exception thrown; Generic.KeyNotFoundException
contact.GetAttributeValue<string>("middlename"); //returns null


Update record: 

    The update is very similar to create. Create your entity object, and set your fields. The attributes will override any existing value in 365, even if you are resetting the same value – this can cause workflows or plugins to execute. You also need to supply the id of the record you wish to update, I normally use the constructor but you can also set the id property on the entity object directly.

Entity contact = new Entity("contact", contactId);
contact["firstname"] = "Sam";
contact["lastname"] = "Boss";

Then call the update function on the service, unlike create, there is no return value.
service.Update(contact);

Delete record: 

    The easiest method to use, delete will remove a record from 365, there isn’t an undo function, so be careful. Simply supply the entity schema name and record id to the service delete function, there is no return value.

service.Delete("contact", contactId);



Click here to Start with Sample Plugin Code.



To be continued .....