In previous blog we have created Custom API and related records. In today’s blog we will write .Net code on our Custom API message.
Let me explain what we are going to do in our plugin code. We will pass Contact Record Guid as input parameter and then in plugin code we will use this record Guid to fetch required Contact entity details using Service Retrieve method.
Once we get the record we will return the data in JSON and set it in Output parameter which we will from Postman, Rest Builder and C# code.
Step – 1
Create new class library project and add new class then copy and paste below code.
using System;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using XrmExtensions;
namespace Microsoft.Crm.Sdk.Samples.TestingCustomAPI
{
[DataContract]
public class CRMContact
{
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
[DataMember]
public string EmailAddress { get; set; }
[DataMember]
public string MobilePhone { get; set; }
[DataMember]
public string Country { get; set; }
[DataMember]
public string ZIPCode { get; set; }
}
public class TestingCustomAPI : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// Obtain the tracing service
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));
// Obtain the execution context from the service provider.
IPluginExecutionContext context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));
// Obtain the organization service reference.
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
if (context.MessageName.Equals("cr234_TestCustomAPI") && context.Stage.Equals(30))
{
try
{
string dataRequest = string.Empty;
if (context.InputParameters.Contains("DataRequest") && context.InputParameters["DataRequest"] != null)
{
dataRequest = (string)context.InputParameters["DataRequest"];
}
if (!string.IsNullOrEmpty(dataRequest))
{
Entity contact = service.Retrieve("contact", Guid.Parse(dataRequest), new Xrm.Sdk.Query.ColumnSet(true));
if (contact != null)
{
using (MemoryStream SerializememoryStream = new MemoryStream())
{
//create a sample data of type Student Class add details
CRMContact crmContact = new CRMContact();
if (contact.Attributes.Contains(Contact.FirstName.ToString()))
{
crmContact.FirstName = contact.Attributes[Contact.FirstName.ToString()].ToString();
}
if (contact.Attributes.Contains(Contact.LastName.ToString()))
{
crmContact.LastName = contact.Attributes[Contact.LastName.ToString()].ToString();
}
if (contact.Attributes.Contains(Contact.PersonalEmail.ToString()))
{
crmContact.EmailAddress = contact.Attributes[Contact.PersonalEmail.ToString()].ToString();
}
if (contact.Attributes.Contains(Contact.MobilePhone.ToString()))
{
crmContact.MobilePhone = contact.Attributes[Contact.MobilePhone.ToString()].ToString();
}
if (contact.Attributes.Contains(Contact.Country_Region.ToString()))
{
crmContact.Country = contact.Attributes[Contact.Country_Region.ToString()].ToString();
}
if (contact.Attributes.Contains(Contact.ZIP_PostalCode.ToString()))
{
crmContact.ZIPCode = contact.Attributes[Contact.ZIP_PostalCode.ToString()].ToString();
}
// initialize DataContractJsonSerializer object and pass Student class type to it
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(CRMContact));
//write newly created object(NewStudent) into memory stream
serializer.WriteObject(SerializememoryStream, crmContact);
SerializememoryStream.Position = 0;
//use stream reader to read serialized data from memory stream
StreamReader sr = new StreamReader(SerializememoryStream);
//get JSON data serialized in string format in string variable
string Serializedresult = sr.ReadToEnd();
//Serialize the Entity Object and set it to Output parameter
context.OutputParameters["DataResponse.TestCustomAPI"] = Serializedresult;
}
}
}
}
catch (FaultException<OrganizationServiceFault> ex)
{
throw new InvalidPluginExecutionException("An error occurred in TestCustomAPI.", ex);
}
catch (Exception ex)
{
tracingService.Trace("TestCustomAPI: {0}", ex.ToString());
throw;
}
}
else if (context.MessageName.Equals("cr234_TestCustomAPI") && context.Stage.Equals(20))
{
try
{
string dataRequest = string.Empty;
if (context.InputParameters.Contains("DataRequest") && context.InputParameters["DataRequest"] != null)
{
dataRequest = (string)context.InputParameters["DataRequest"];
context.InputParameters["DataRequest"] = "472aa6d8-c133-eb11-a813-000d3af020c4";
}
}
catch (FaultException<OrganizationServiceFault> ex)
{
throw new InvalidPluginExecutionException("An error occurred in PreEventTestCustomAPI.", ex);
}
catch (Exception ex)
{
tracingService.Trace("PreEventTestCustomAPI: {0}", ex.ToString());
throw;
}
}
else
{
tracingService.Trace("TestCustomAPI plug-in is not associated with the expected message or is not registered for the main operation.");
}
}
}
}
Key Points –
- First we are checking Message name from context “context.InputParameters.Contains(“DataRequest”)”
- We are also checking if Stage/Plugin execution pipeline is Main Operation
- Extracting the input parameter value and converting it into Guid. We could also use Guid Data type as Request Parameter. I created as String this is why I need to convert this to Guid.
- Now I am getting required fields and forming the Json to set in output parameter
Step – 2
Register your assembly and update Custom API record Plugin Type field with your class name which you have created in previous blog.
Step – 3
Once you are done with the registration of Assembly. Open Rest Builder and find your custom API and execute by passing Contact record guid in input parameter.

Step – 4
We will execute our Custom API from C# code
ParameterCollection parameters = new ParameterCollection();
parameters.Add("DataRequest", "2902e1e5-5a43-eb11-a812-6045bd726160");
OrganizationRequest requestCustomApi = new OrganizationRequest()
{
RequestName = "cr234_TestCustomAPI",
Parameters = parameters
};
OrganizationResponse responseCustomApi = crmSvc.Execute(requestCustomApi);
var stringProperty = (string)responseCustomApi.Results["DataResponse.TestCustomAPI"];
Output
{“Country”:”India”,”EmailAddress”:”test@t.com”,”FirstName”:”Test”,”LastName”:”Test”,”MobilePhone”:null,”ZIPCode”:”824230″}
Step – 5
Test your Custom API from Postman

Hope this helps!
Next blog we will explore how we can also register PreOperation step on our Custom API message which was not possible through Custom Action
3 thoughts on “{Microsoft Dataverse} Explore Custom API feature Part-3 in Dynamics 365”