Archive

Posts Tagged ‘C#’

[Code Snippet] Set Business process flow (BPF) stage using C#

October 15, 2020 Leave a comment

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.

‘Employer flow’ is BPF Entity

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’.
‘BPF Test’ record’s stage 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);

🙂

Categories: CRM Tags: , , ,

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;

🙂

 

Categories: Misc Tags: , ,

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’

PM_2

  • 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’

PM_1

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.

PM_3

If anyone having struggling to use Sandblast API’s, post in comments section and I will address.

🙂

 

Categories: Misc Tags: , , ,

C# – Configuration section cannot be used at this path

January 22, 2019 Leave a comment

Other day , while accessing my WCF service (i.e., .svc) from IIS server, I was getting below error:

iis_3

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

iis_1

  • 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.

iis_2

  • Restart your web app
  • Try to browse the files and they should work now.

iis_4

🙂

 

C# – SQL – Bulk Insert records from Data Table and CSV

March 31, 2018 1 comment

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.

Data Table 1

  • 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.

Insert 1

  • Below is the query

Bulk Insert {SQL Table Name}

from ‘CSV File Path’

with
(rowterminator=’\n’,fieldterminator=’,’)

Insert 2

Categories: SQL Tags: , ,

Stack overflow error while disposing object – C#

September 27, 2014 Leave a comment

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;

}

🙂

Categories: Misc Tags: , ,

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.

Composite XML

Composite XML

  • Copy the XML file content.
  • Open a new Class file “FruitsWrapper.cs” in Visual Studio 2012
  • Select “EDIT -> Paste Special -> Paste XML As Classes”

Paste Special XML As Class

Paste Special XML As Class

  • Now you get XML wrapper class on your Class file

Generated XML Wrapper Class

Generated XML Wrapper Class

  • 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.

Categories: Misc Tags: , , ,

Reflection with method overloading C#

July 16, 2014 1 comment

I have a class with 3 overloaded methods and when try to invoke method’s using Reflection, I was gettingAvoiding 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

Reflection Overload Result

Reflection Overload Result

🙂

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.

🙂