Working with JSON objects in Dynamics CRM Plugins

By | October 7, 2016

While working with Dynamics CRM plugin, we encountered a scenario where we were calling a Web API, which returns data in JSON format.

Normally .NET framework provides many methods to use JSON in C# code, many third party solutions such as Newtonsoft.Json library are available. Mostly we use JavaScriptSerializer to read JSON data.

However, when we register Plugin inside Sandbox, and if we try to use javascriptSerializer method in plugin, it will throw security exception error as show below:

The error message we get:

Unhandled Exception: Microsoft.Crm.CrmException: Unexpected exception from plug-in (Execute): XXXXXXXX.CRM2015.WorkflowActivities.XXXXXXXX: System.MethodAccessException: Attempt by security transparent method ‘XXXXXXXX.CRM2015.WorkflowActivities.XXXXXXXX.SetLocationInfo(Microsoft.Xrm.Sdk.IOrganizationService, Microsoft.Xrm.Sdk.ITracingService, System.String)’ to access security critical method ‘System.Web.Script.Serialization.JavaScriptSerializer..ctor()’ failed.

Assembly ‘XXXXXXXX.CRM2015.WorkflowActivities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3f9fc15734725b08’ is partially trusted, which causes the CLR to make it entirely security transparent regardless of any transparency annotations in the assembly itself.  In order to access security critical code, this assembly must be fully trusted.

Assembly ‘System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’ is a conditionally APTCA assembly which is not enabled in the current AppDomain.  To enable this assembly to be used by partial trust or security transparent code, please add assembly name ‘System.Web.Extensions, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9’ to the the PartialTrustVisibleAssemblies list when creating the AppDomain.
at Microsoft.Crm.Sandbox.SandboxCodeUnit.Execute(IExecutionContext context)
at Microsoft.Crm.Workflow.Services.ProxyCustomActivity.Execute(CodeActivityContext executionContext)

This error occurs since we cannot access third party dll’s in CRM context.

To resolve this, we can use either ILMerge(utility for merging multiple .NET assemblies into a single one).

However there is an alternate way to get it done without using third party solution, by using DataContractJsonSerializer in CRM plugin.

Below code will demonstrate you how to use DataContractJsonSerializer in CRM plugin.

To use JSON in CRM plugin

  1. Create a DataContract class that will define datamodel for JSON data that we receive from Web API.
    [DataContract]
        public class Student
        {
            [DataMember]
            public string FullName { get; set; }
            [DataMember]
            public string JobTitle { get; set; }
            [DataMember]
            public string Contact { get; set; }
            [DataMember]
            public string Country { get; set; }
            [DataMember]
            public string ZIPCode { get; set; }
           
        }
  • Deserialize Data obtained in JSON string to an object
using (MemoryStream DeSerializememoryStream = new MemoryStream())
                {
                    //Json String that we get from web api 
                    string ResponseString = "{\"FullName\":\"" + "Sam" + "\",\"JobTitle\":\"" + "Developer" + "\",\"Contact\":\"" + "808-124567" + "\",\"Country\":\"" + "India" + "\",\"ZIPCode\":\"" + "400005" + "\"}";

                    //initialize DataContractJsonSerializer object and pass Student class type to it
                    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Student));

                    //user stream writer to write JSON string data to memory stream
                    StreamWriter writer = new StreamWriter(DeSerializememoryStream);
                    writer.Write(ResponseString);
                    writer.Flush();

                    DeSerializememoryStream.Position = 0;
                    //get the Desrialized data in object of type Student
                    Student SerializedObject = (Student)serializer.ReadObject(DeSerializememoryStream);
                }
  • Serialize Data in JSON string
using (MemoryStream SerializememoryStream = new MemoryStream())
                {
                    //create a sample data of type Student Class add details
                    Student NewStudent = new Student();
                    NewStudent.FullName = "Sam";
                    NewStudent.JobTitle = "Developer";
                    NewStudent.Contact = "808-2125454";
                    NewStudent.Country = "India";
                    NewStudent.ZIPCode = "400005";

                    //initialize DataContractJsonSerializer object and pass Student class type to it
                    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Student));
                    //write newly created object(NewStudent) into memory stream
                    serializer.WriteObject(SerializememoryStream, NewStudent);
                    
                    //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();
                }

Hope this will help you in using JSON data in Dynamics CRM plugin!

70% of global 2000 companies apply gamification to improve productivity and returns!

Gamifics365 – Spin the magic of games within Microsoft Dynamics 365 CRM to improve user adoption, enhance productivity, and achieve company goals!

6 thoughts on “Working with JSON objects in Dynamics CRM Plugins

  1. Mohit

    Hi,

    I have also created a similiar plugin where i am getting json data.
    but my requirement is i want use this json data my ms crm account form.
    What should i do?
    My flow is:
    on click of a button a js will be fired which will have this json data and will call a action and action will again trigger my plugin.
    I need to display this json data on the account form.

    1. Inogic

      To convert the object to JSON please add below two updated lines in your code to achieve the result.

      using (MemoryStream SerializememoryStream = new MemoryStream())
      {
      //create a sample data of type CaseDetails Class add details
      CaseDetails caseD = new CaseDetails();
      caseD.CaseNumber = “123”;
      caseD.Title = “abc”;
      //initialize DataContractJsonSerializer object and pass Student class type to it
      var serializer = new DataContractJsonSerializer(caseD.GetType(), new DataContractJsonSerializerSettings
      {
      UseSimpleDictionaryFormat = true
      });
      //write newly created object(NewStudent) into memory stream
      serializer.WriteObject(SerializememoryStream, caseD);

      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();
      }

      Hope this helps.

      Thanks!

  2. Ashwini

    Hello, AM not able to convert object to json with above code, please help.
    using (MemoryStream SerializememoryStream = new MemoryStream())
    {
    //create a sample data of type Student Class add details
    CaseDetails caseD = new CaseDetails();
    caseD.CaseNumber = “123”;
    caseD.Title = “abc”;

    //initialize DataContractJsonSerializer object and pass Student class type to it
    System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(CaseDetails));
    //write newly created object(NewStudent) into memory stream
    serializer.WriteObject(SerializememoryStream, caseD);

    //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();
    }
    sr.BaseStream.ReadTimeout ‘sr.BaseStream.ReadTimeout’ threw an exception of type ‘System.InvalidOperationException’

    1. inogic

      Hi,

      To convert the object to JSON please add below two updated lines in your code to achieve the result.

      using (MemoryStream SerializememoryStream = new MemoryStream())
      {
      //create a sample data of type CaseDetails Class add details
      CaseDetails caseD = new CaseDetails();
      caseD.CaseNumber = “123”;
      caseD.Title = “abc”;
      //initialize DataContractJsonSerializer object and pass Student class type to it
      var serializer = new DataContractJsonSerializer(caseD.GetType(), new DataContractJsonSerializerSettings
      {
      UseSimpleDictionaryFormat = true
      });
      //write newly created object(NewStudent) into memory stream
      serializer.WriteObject(SerializememoryStream, caseD);

      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();
      }

      Hope this helps.

      Thanks!

  3. Kevin Murphy

    has anyone measure the overhead of this convversion? Advisable in using a syncronous call or best for async? Best for limited number of fields or ok for large numbers? impact on memory use?

    1. Inogic

      If you have a very large object then it can slow down or even halt the execution. You should optimize the memory usage. You can refer this article to avoid this situation and to improve the performance.

      Hope this helps!

Comments are closed.