C#, CRM

CRM Plugins – Input Parameters and Early Binding

I recently came across this problem looking at a CRM instance that had been upgraded to use early-binding. They had done something like below:

var accountInputParameters = ((Entity)context.InputParameters["Target"]).ToEntity<Account>();

This takes the InputParameters (which is of type Entity) and then bound it to the Account early-bound type.

While this seems like a good idea on the surface, as it allows all the fields of the Account to be accessed using strongly typed properties, the customer reported some strange behaviour on their Accounts.

Continue reading

C#, JavaScript, Web Services

JSON and the JavaScriptSerializer

Today I was trying to write a web service method that would allow me to run some stored procedures on my table. Rather than having multiple web service calls for each stored procedure I wanted to come up with some generic functions that could call a range of stored procedures:

  1. Scalar
  2. NonQuery
  3. Retrieve DataTable

Each of these stored procedures require a Stored Procedure name and a collection of SQL Parameters. I decided to instead take a JSON string which would be easy to create from the client and easy to parse on the server.

Here’s the JSON snippet that I came up with

{
    "procName" : "sp_updateUser",
    "procVars" : 
       [
          {
              "paramName" : "firstname",
              "paramValue" : "jasonscript",
              "paramDirection": "Input"
          },
          {
              "paramName" : "planet",
              "paramValue" : "Earth",
              "paramDirection": "Input"
          },
       ]
 }

Pretty simple. Then in my web service I created two classes:

  1. for my container
    internal class Proc
    {
        public string procName;
        public List<ProcArg> procVars;
    
        public Proc()
        {
            this.procName = "";
            this.procVars = new List<ProcArg>();
        }
    }
  2. for my parameters:
    internal class ProcArg
    {
        public string paramName
        public string paramValue
        public string paramType;
    
        public ProcArg()
        {
            this.paramName = "";
            this.paramValue = "";
            this.paramType = "";
        }
    }

Next step was to parse the JSON string to these classes

var jsSerializer = new JavaScriptSerializer();
var spInfo = jsSerializer.Deserialize<Proc>(json);

Now I can access everything from my JSON string in my spInfo object

spInfo.procName               == "sp_updateUser"
spInfo.procVars.Count         == 2
spInfo.procVars[0].paramName  == "jasonscript"
spInfo.procVars[1].paramValue == "Earth"

The JavaScriptSerializer will attempt to match the keys of the JSON string to the public properties of each Class.

JSON.procName                 == Proc.procName

These mappings can be altered using DataMember attributes. For example, I could re-write the Proc class as follows:

internal class Proc
{
    [DataMember(Name = "procName")]      // specify the name to use for serializing
    public string spName;                // renamed so no longer matches JSON snippet
    public List<ProcArg> procVars;

    public Proc()
    {
        this.spName = "";
        this.procVars = new List<ProcArg>();
    }
}

Thanks to the DataMember property, the JavaScriptSerializer can still map the JSON string to the class property