Archive
[Code Snippet] Set Business process flow (BPF) stage using C#
Assume you have a BPF with 3 Stages on an Entity ‘Employer’. When you create a new ‘Employer’ record, by default ‘Stage-1’ gets set.
What if you have to create the ‘Employer’ record with a different stage.
Lets see how to create a record and set the desired BPF stage with an example entity ‘Employer’.
I’ve an ‘Employer’ entity and a BPF name ‘Employer flow’ with 3 stages named ‘Basic Details’, ‘Address’ and ‘Experience’.

Key point to notice is, when ever you create a BPF a new entity gets created with the given BPF name.

Following are the steps to create a ‘Employer’ record and set the BPF stage to ‘Experience’.
- Query ‘Workflow’ entity to get the ‘BPF ID’ by passing the BPF entity schema name (i.e., crf10_employerflow).
var queryEmployerBPF = new QueryExpression { EntityName = "workflow", ColumnSet = new ColumnSet(true), Criteria = new FilterExpression { Conditions = { new ConditionExpression { AttributeName = "uniquename", Operator = ConditionOperator.Equal, Values = { "crf10_employerflow" } } } } }; var retrievedBPF = ConnectionManager.CrmService.RetrieveMultiple(queryEmployerBPF).Entities[0]; var _bpfId = retrievedBPF.Id;
- Query Process Stage by passing ‘BPF ID’ fetched in previous step.
var queryPS = new QueryExpression{ EntityName = "processstage", ColumnSet = new ColumnSet(true), Criteria = new FilterExpression{ Conditions ={ new ConditionExpression{ AttributeName = "processid", Operator = ConditionOperator.Equal, Values={ _bpfId } } } } };
- Copy the ‘Stage’ GUID’s which will be used in next steps.
- Create the ‘Employer’ record, which also creates record in ‘BPF entity’ (i.e., Employer Flow).
Entity entEmployer = new Entity("crf10_employer"); entEmployer["crf10_name"] = "BPF Test"; //entEmployer["processid"] = Guid.Empty; var violationID = ConnectionManager.CrmService.Create(entEmployer);
- Fetch the ‘BPF entity’ (i.e., Employer Flow) record, which auto created in previous step, using ‘RetrieveProcessInstancesRequest’ request.
var procOpp2Req = new RetrieveProcessInstancesRequest { EntityId = violationID, EntityLogicalName = "crf10_employer" }; var procOpp2Resp = (RetrieveProcessInstancesResponse)ConnectionManager.CrmService.Execute(procOpp2Req);
- Update ‘activestageid’ field of the ‘BPF entity’ (i.e., Employer Flow) record fetched in previous step, with the desired stage GUID captured in Step #2.

// Declare variables to store values returned in response int processCount = procOpp2Resp.Processes.Entities.Count; var activeProcessInstance = procOpp2Resp.Processes.Entities[0]; // First record is the active process instance var _processOpp2Id = activeProcessInstance.Id; // Id of the active process instance, which will be used // Retrieve the process instance record to update its active stage ColumnSet cols1 = new ColumnSet(); cols1.AddColumn("activestageid"); Entity retrievedProcessInstance = ConnectionManager.CrmService.Retrieve("crf10_employerflow", _processOpp2Id, cols1); // Update the stage to 'Experience' by passing GUID (i.e.,"05aeaf03-e135-40ac-8ae7-cafc7d746a02") retrievedProcessInstance["activestageid"] = new EntityReference("processstage", new Guid("05aeaf03-e135-40ac-8ae7-cafc7d746a02")); ConnectionManager.CrmService.Update(retrievedProcessInstance);
- Open the record from the App and the stage should set to ‘Experience’.

- Check the BPF records and you should see ‘Active Stage’ got set to ‘Experience’ (This is optional step and for your learning).

- Below is the complete snippet.
var queryEmployerBPF = new QueryExpression { EntityName = "workflow", ColumnSet = new ColumnSet(true), Criteria = new FilterExpression { Conditions = { new ConditionExpression { AttributeName = "uniquename", Operator = ConditionOperator.Equal, Values = { "crf10_employerflow" } } } } }; var retrievedBPF = ConnectionManager.CrmService.RetrieveMultiple(queryEmployerBPF).Entities[0]; var _bpfId = retrievedBPF.Id; var queryPS = new QueryExpression { EntityName = "processstage", ColumnSet = new ColumnSet(true), Criteria = new FilterExpression { Conditions = { new ConditionExpression { AttributeName = "processid", Operator = ConditionOperator.Equal, Values={ _bpfId } } } } }; var retrievedPS = ConnectionManager.CrmService.RetrieveMultiple(queryPS); // Copy the Stage GUID's using below loop. foreach (var stage in retrievedPS.Entities) { Console.WriteLine($"Stage Name : {stage["stagename"]}"); Console.WriteLine($"Stage ID : {stage["processstageid"]}"); } //Create 'Employer' record var entEmployer = new Entity("crf10_employer"); entEmployer["crf10_name"] = "BPF Test"; //entEmployer["processid"] = Guid.Empty; var violationID = ConnectionManager.CrmService.Create(entEmployer); var procOpp2Req = new RetrieveProcessInstancesRequest { EntityId = violationID, EntityLogicalName = "crf10_employer" }; var procOpp2Resp = (RetrieveProcessInstancesResponse)ConnectionManager.CrmService.Execute(procOpp2Req); // Declare variables to store values returned in response int processCount = procOpp2Resp.Processes.Entities.Count; var activeProcessInstance = procOpp2Resp.Processes.Entities[0]; // First record is the active process instance var _processOpp2Id = activeProcessInstance.Id; // Id of the active process instance, which will be used // Retrieve the process instance record to update its active stage var cols1 = new ColumnSet(); cols1.AddColumn("activestageid"); var retrievedProcessInstance = ConnectionManager.CrmService.Retrieve("crf10_employerflow", _processOpp2Id, cols1); // Update the stage to 'Experience' by passing GUID (i.e.,"05aeaf03-e135-40ac-8ae7-cafc7d746a02") retrievedProcessInstance["activestageid"] = new EntityReference("processstage", new Guid("05aeaf03-e135-40ac-8ae7-cafc7d746a02")); ConnectionManager.CrmService.Update(retrievedProcessInstance);
đ
C# Error while calling API – Could not create SSL/TLS secure channel
Other day, we were getting following error while calling SSL enables 3rd party API from C# console.
The request was aborted: Could not create SSL/TLS secure channel
Fix:
- Add below statement before making your API call, which validates the SSL certification.
ServicePointManager.ServerCertificateValidationCallback = delegate (object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
};
- Include following namespaces
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
đ
Post a File and Data to SandBlast API using Postman and generate C# code
We got a requirement to use SandBlast Threat Extraction process, for cleansing the files.
SandBlast Threat Extraction, is a solution by ‘Check Point’ company, which removes exploitable content, including active content and embedded objects, reconstructs files to eliminate potential threats.
‘Threat Extraction’ Upload API, requires following parameters
- Header
- Authorization
- Content-Type
- Body
- File Content
- request (This is string)
If you notice, we need to pass ‘File’ as well as ‘Data’ to the API.
As of now, Sandblast doesn’t have a native .Net library to make API calls. So I’ve used Postman tool as a starting point for my development.
Below is the step-by-step, to pass ‘File’ and ‘Data’ in request ‘Body’, using Postman
- Open Postman tool
- Create a new ‘Request’
- Set the method as ‘Post’ and URL.
- From the ‘Body’ tab, select ‘form-data’ option
- To pass the ‘File’, add a new ‘KEY’ of type ‘File’ and browse the file in ‘VALUE’ parameter.
- To pass the ‘Data’, add a new ‘KEY’ of type ‘Text’ and set the ‘VALUE’
Generate C# code from the Request:
- Postman has an amazing feature to generate the code in your required language.
- Click on ‘Code’ link and for C#, choose ‘C# (RestSharp)’ option.
- In your C# project, add RestSharp NuGet package.
- Paste the code in your class file and you are good to go now.
If anyone having struggling to use Sandblast API’s, post in comments section and I will address.
đ
C# – Configuration section cannot be used at this path
Other day , while accessing my WCF service (i.e., .svc) from IIS server, I was getting below error:
Reason:
- In my case, Issue is with missing ‘Write’ privilege for ‘Windows Authentication’ in IIS server.
Fix:
To fix the issue follow below steps
- Connect to your IIS server
- Select the ‘Server node’ (i.e., Your machine name) from left ‘Connections’ pane
- On the right ‘Features View’ pane, select ‘Feature Delegation’ option
- From the list, select ‘Authentication – Windows’ option and make sure the delegation set to ‘Read\Write’
- If its only ‘Read’, click on ‘Read/Write’ link from right side ‘Set Feature Delegation’ pane.
- Restart your web app
- Try to browse the files and they should work now.
đ
C# – SQL – Bulk Insert records from Data Table and CSV
In my previous article I provided the steps to update records in single transaction using SQL âTable-Valued Parameter Typesâ.
In this article, lets see an easy way to bulk insert the records using SQLBulkCopy
What is SQLBulkCopy:
- SQLBulkCopy class comes with ‘System.Data’ namespace and can be used to write/Insert data to SQL Server tables.
- Though there are other ways to load data into a SQL Server table (i.e., INSERT statements, for example) but ‘SQLBulkCopy’ offers a significant performance advantage.
Below are the steps to use SQLBulkCopy with the combination of ‘Data Table’
Steps:
To simplify the explanation, I am taking a âStudentâ table with 3 columns.
- Create a ‘Student’ table.
- In C# console application, prepare a ‘Data Table’ with the structure similar to ‘Student’ SQL table.
tableStudents = new DataTable(âStudentâ);
tableStudents.Columns.Add(âStudentIDâ, typeof(string));
tableStudents.Columns.Add(âStudentNameâ, typeof(string));
tableStudents.Columns.Add(âCityâ, typeof(string));// Add âStudentâ data as Rows to the Data Table
DataRow rowStudent = tableStudents.NewRow();
rowStudent[âStudentIDâ] = âRJ001â
rowStudent[âStudentNameâ] = âRajeevâ;
rowStudent[âCityâ] = âHydâ;//Add the Data Row to Table
tableStudents.Rows.Add(rowStudent);
- Instantiate and execute the ‘SQLBulkCopy’ by passing the Data Table
using (SqlBulkCopy bulkCopy = new SqlBulkCopy({SQLConnection}, SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.UseInternalTransaction, null))
{
bulkCopy.DestinationTableName = “Student“; // Your SQL Table name//Optional mappings. Not required, if your ‘Data Table’ column names match with ‘SQL Table’ column names
bulkCopy.ColumnMappings.Add(“StudentID”, “StudentID”);
bulkCopy.ColumnMappings.Add(“StudentName”, “StudentName”);
bulkCopy.ColumnMappings.Add(“City”, “City”);
bulkCopy.WriteToServer(tableStudents);
isSuccuss = true;
}
- Execute the code which inserts rows from ‘Data Table’ to ‘Student’ SQL table.
Now lets see how to insert the CSV data to SQL table with query.
Note: You can also do the same with SQL Import Wizard
Bulk insert records from CSV to SQL Table:
- Assume that you have data available in a CSV file and want to insert them as records in SQL Table.
- Below is the query
Bulk Insert {SQL Table Name}
from ‘CSV File Path’
with
(rowterminator=’\n’,fieldterminator=’,’)
Stack overflow error while disposing object â C#
I have a class “ABC” which implements âIDisposableâ interface and having below Dispose method.
Public Class ABC : IDisposable {
public void Dispose()Â Â Â Â Â Â {
this.Dispose(true);
}
}
When I run the application I was getting âStack Overflowâ error because the Dispose() method getting called recursively and went in to an infinite loop.
Fix :
- Prevent the Dispose() recursive call by using flag and the logic is as below
 private bool disposed = false;
public void Dispose()Â {
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)Â {
if (this.disposed)Â {
return;
}
this.disposed = true;
}
đ
XML to strongly typed object in C#
Assume you have composite XML and you want read the XML field values in your C# project, the simplest way is to convert in to Strongly type object and read as parameters.
It involves two steps as mentioned below
Generate XML Wrapper ClassÂ
- “Fruits.xml” is your XML file.
- Copy the XML file content.
- Open a new Class file “FruitsWrapper.cs” in Visual Studio 2012
- Select âEDIT -> Paste Special -> Paste XML As Classesâ
- Now you get XML wrapper class on your Class file
- Save the file
Convert XML to Class
- To test the Conversion and read the XML data
- Take a console application and paste below code
static void Main(string[] args){
const string fruitsXmlPath = @”c:\Fruits.xml”;
// Set your Root Element Name (i.e., <Fruits> is the root node of our XML)
var xRoot = new XmlRootAttribute { ElementName = “Fruits”, IsNullable = true };
var xmlSerializer = new XmlSerializer(typeof(Fruits), xRoot);
var fruits = (Fruits)xmlSerializer.Deserialize(new FileStream(fruitsXmlPath, FileMode.Open));
// Read XML node values as Object Properties
Console.WriteLine(“Fruit Name” + fruits.CitrusFruits.Fruit.Name);
Console.WriteLine(“Fruit Price” + fruits.CitrusFruits.Fruit.Price);
}
This approach is useful when you have your application’s configuration details provided in an XML file and if the file is complex and big.
Note â If you donât have âPaste Special -> Paste XML As Classesâ feature in your Visual Studio, you can use XSD.exe tool to generate wrapper class from XML.
Reflection with method overloading C#
I have a class with 3 overloaded methods and when try to invoke method’s using Reflection, I was getting âAvoiding an ambiguous match exceptionâ exception.
Below is the way to invoke overload methods using Reflection, which solved my exception.
Letâs take a class with 3 overload methods.
Class Structure
namespace MyNamespace{
public class CallMe{
public string MyName(){
return “You donât have name”;
}
public string MyName(string firstName){
return “Your name is ” + firstName;
}
public string MyName(string firstName, string lastName){
return “Your name is ” + firstName + lastName;
}
}
Here is the way to invoke methods using Reflection
C# Code to call the Generic Method
// Load .dll
Assembly assembly = Assembly.LoadFile(“{Physical path of }MyNamespace.dll”);
// Set the Class type as âNamespace.Classnameâ
Type classType = assembly.GetType(“ReflectionClass.CallMe”);
// One of my methods expects 1 string hence creating MethodInfo object with 1 Type[] parameter
MethodInfo methodWithOneParameter = classType.GetMethod(“MyName”, new Type[] { typeof(string) });
// One of my methods expect 2 string parameters hence creating MethodInfo object with 2 Type[] parameters.
MethodInfo methodWithTwoParameter = classType.GetMethod(“MyName”, new Type[] { typeof(string), typeof(string) });
// To invoke overload with no parameters, provide an empty Type array to GetMethod’s second parameter
MethodInfo methodWithNoParameter = classType.GetMethod(“MyName”, new Type[0]);
// Invoke Methods
var resultMethodWithOneParameter = InvokeMethod(classType, methodWithOneParameter, new string[] { “Rajeev” });
var resultMethodWithTwoParameter = InvokeMethod(classType, methodWithTwoParameter, new string[] { “Rajeev”, “Pentyala” });
var resultMethodWithNoParameter = InvokeMethod(classType, methodWithNoParameter, null);
//Â Display Results
Console.WriteLine(“ResultMethodWithOneParameter – ” + resultMethodWithOneParameter.ToString());
Console.WriteLine(“ResultMethodWithTwoParameter – ” + resultMethodWithTwoParameter.ToString());
Console.WriteLine(“ResultMethodWithNoParameter – ” + resultMethodWithNoParameter.ToString());
 C# Generic Method to Invoke methods
      // Generic method Invokes methods and return Result as Object
public static object InvokeMethod(Type classType, MethodInfo methodInfo, object[] parametersArray){
object result = null;
if (classType != null) {
if (methodInfo != null) {
ParameterInfo[] parameters = methodInfo.GetParameters();
object classInstance = Activator.CreateInstance(classType, null);
if (parameters.Length == 0) {
//This works fine
result = methodInfo.Invoke(classInstance, null);
}
else {
//The invoke does NOT work it throws “Object does not match target type”
result = methodInfo.Invoke(classInstance, parametersArray);
}
}
}
return result;
}
We get the response as below
đ
Separating alphabets and digits from Alphanumeric stringâ C#
We got a requirement to separate alphabets and digits from alphanumeric string as groups.
Letâs say my alphanumeric string is âHel00Wor11DDâ and I need to get
- Alphabet group as âHel,Wor,DDâ
- Â Digit group as â00,11â.
Below is the C# code which use Regular expressions and achieve the same
var digitGroup = newList<string>();
var alphabetGroup = newList<string>();
Match regexMatch = null;
string myString = “Hel00Wor11DD”;
while (myString.Length > 0){
if ((regexMatch = Regex.Match(myString, “\\d”)).Success){
// If myString is not starting with digit
if (regexMatch.Index > 0) {
alphabetGroup.Add(myString.Substring(0, regexMatch.Index));
}
// If myString is starting with digits but has subsequent alphabets
elseif ((regexMatch = Regex.Match(myString, “\\D”)).Success) {
digitGroup.Add(myString.Substring(0, regexMatch.Index));
}
// If myString only has digits, no more alphabets
else{
digitGroup.Add(myString.Substring(0));
// No more alphabets
break;
}
myString = myString.Substring(regexMatch.Index);
}
// There are no digits in myString
else{
alphabetGroup.Add(myString);
// No more digits
break;
}
}
When you run above code, you would get Alphabets & Digits separated as Lists.
đ