Tuesday, 21 November 2017

Call any method after OnSave in MS CRM

There are many scenarios which requires a custom action to be performed after saving a record. For example: 
  • Set its status
  • Add a relationship, 
  • Update a field, 
  • Update another record
  • Call a model dialog etc

Microosft SDK has given this feature using which we can easily add or remove any method after save.
methods are:
  • Xrm.Page.data.entity.addOnSave
  • Xrm.Page.data.entity.removeOnSave
Syntax Code:

function addActionToOnSave() {
 Xrm.Page.data.entity.addOnSave(setRecordStatusInactive);
}
 
function removeActionFromOnSave() {
 Xrm.Page.data.entity.removeOnSave(setRecordStatusInactive);
}
 
function setRecordStatusInactive() {
 //code to set record status inactive
}


Hope this will help you.

Friday, 8 September 2017

Ho to Pass parameters to HTML Web resource inside of MS CRM 2011/2013/2015/2016

HTML web resource page can only accept a single custom parameter called data. To pass more than one value in the data parameter, you need to encode the parameters and decode the parameters in our page.
The example can be found in the SDK folder that can be downloaded freely. The path is sdk\samplecode\js\webresources\showdataparams.htm
First we have to create a HTML web resource(Lets say : ViewDataParams.htm) and call it as below by passing parameters:
http://<server name>/WebResources/new_/ViewDataParams.htm?Data=first%3DFirst%20Value%26second%3DSecond%20Value%26third%3DThird%20Value
Using Data parameter we can pass multiple values to HTML web resource.
On the HTML page we can read the values using JavaScript on page load in below ways:
document.onreadystatechange = function () {
if (document.readyState == “complete”) {
getDataParam();
}
}
function getDataParam() {
//Get the any query string parameters and load them
//into the vals array
var vals = new Array();
if (location.search != “”) {
vals = location.search.substr(1).split(“&”);
for (var i in vals) {
vals[i] = vals[i].replace(/\+/g, ” “).split(“=”);
}
//look for the parameter named ‘data’
var found = false;
for (var i in vals) {
if (vals[i][0].toLowerCase() == “data”) {
parseDataValue(vals[i][1]);
found = true;
break;
}
}
if (!found)
{ noParams(); }
}
else {
noParams();
}
}
function parseDataValue(datavalue) {
if (datavalue != “”) {
var vals = new Array();
var message = document.createElement(“p”);
setText(message, “These are the data parameters values that were passed to this page:”);
document.body.appendChild(message);
vals = decodeURIComponent(datavalue).split(“&”);
for (var i in vals) {
vals[i] = vals[i].replace(/\+/g, ” “).split(“=”);
}
//Create a table and header using the DOM
var oTable = document.createElement(“table”);
var oTHead = document.createElement(“thead”);
var oTHeadTR = document.createElement(“tr”);
var oTHeadTRTH1 = document.createElement(“th”);
setText(oTHeadTRTH1, “Parameter”);
var oTHeadTRTH2 = document.createElement(“th”);
setText(oTHeadTRTH2, “Value”);
oTHeadTR.appendChild(oTHeadTRTH1);
oTHeadTR.appendChild(oTHeadTRTH2);
oTHead.appendChild(oTHeadTR);
oTable.appendChild(oTHead);
var oTBody = document.createElement(“tbody”);
//Loop through vals and create rows for the table
for (var i in vals) {
var oTRow = document.createElement(“tr”);
var oTRowTD1 = document.createElement(“td”);
setText(oTRowTD1, vals[i][0]);
var oTRowTD2 = document.createElement(“td”);
setText(oTRowTD2, vals[i][1]);
oTRow.appendChild(oTRowTD1);
oTRow.appendChild(oTRowTD2);
oTBody.appendChild(oTRow);
}
oTable.appendChild(oTBody);
document.body.appendChild(oTable);
}
else {
noParams();
}
}
function noParams() {
var message = document.createElement(“p”);
setText(message, “No data parameter was passed to this page”);
document.body.appendChild(message);
}
//Added for cross browser support.
function setText(element, text) {
if (typeof element.innerText != “undefined”) {
element.innerText = text;
}
else {
element.textContent = text;
}
}
An HTML web resource can accept only the parameters in the following table.
ParameterNameDescription
typenameEntity NameThe name of the entity.
typeEntity Type CodeAn integer that uniquely identifies the entity in a specific organization.
idObject GUIDThe GUID that represents a record.
orgnameOrganization NameThe unique name of the organization.
userlcidUser Language CodeThe language code identifier being used by the current user.
orglcidOrganization Language CodeThe language code identifier that represents the base language for the organization.
dataOptional Data ParameterAn optional value that may be passed.
formidForm IdThe GUID that represents a form ID.
entrypointEntry PointA string value. This parameter is intended to be passed as an optional value to web resources opened as custom help content for an entity. When enabled, the custom help URL will include a value of either “form” or “hierarchychart”. More information: Add custom help content



Credit: To whom I follow a great blogger: Sanjaya

Extend your CRM Entity class to do all common stuff easily

Hi All,

Today I'm gonna share my one month efforts with you.

While extending CRM using CRM SDK to all my customers every time I have to write statements for following repeatative work:

You can simply use below class and use all common extended methods while writing custom logic.

Hope this will save lots of your time.

 public enum FetchNodeType
    {
        Unknown = 0,
        String = 1,
        EntityReferenceName = 2,
        PrimaryKey = 3,
        OptionSetValueId = 4,
        OptionSetValueName = 5,
        DateTime = 6,
        EntityReferenceId = 7,
        FormattedValue = 8,
        Double = 9,
        Boolean = 10
    }

 public static class EntityExtension
    {
        public static string GetValue(this Entity entity, string attributeName, FetchNodeType nodeType)
        {
            if (entity == null)
                return string.Empty;

            var aliasedValue = entity.GetAttributeValue<AliasedValue>(attributeName);
            if (aliasedValue == null)
                return string.Empty;

            switch (nodeType)
            {
                case FetchNodeType.String:
                    return (string)aliasedValue.Value;
                case FetchNodeType.EntityReferenceName:
                    return ((EntityReference)aliasedValue.Value).Name;
                case FetchNodeType.PrimaryKey:
                    return ((Guid)aliasedValue.Value).ToString();
                case FetchNodeType.OptionSetValueId:
                    return ((OptionSetValue)aliasedValue.Value).Value.ToString();
                case FetchNodeType.OptionSetValueName:
                case FetchNodeType.DateTime:
                    return entity.FormattedValues.ContainsKey(attributeName) ? entity.FormattedValues[attributeName] : string.Empty;
                case FetchNodeType.EntityReferenceId:
                    return ((EntityReference)aliasedValue.Value).Id.ToString();
                case FetchNodeType.FormattedValue:
                    return entity.FormattedValues.ContainsKey(attributeName) ? entity.FormattedValues[attributeName] : string.Empty;
                case FetchNodeType.Double:
                    return aliasedValue.Value.ToString();
                case FetchNodeType.Boolean:
                    return ((Boolean)aliasedValue.Value == false) ? "No" : "Yes";
                case FetchNodeType.Unknown:
                default:
                    break;
            }
            return string.Empty;
        }

        public static void SetValue(this Entity entity, string attributeName, string attributeType, string value, string lookupEntityName)
        {
            switch (attributeType.ToLowerInvariant())
            {
                case "string":
                case "memo":

                    if (!entity.Attributes.Contains(attributeName))
                    {
                        entity.Attributes.Add(attributeName, value);
                    }
                    else
                    {
                        entity.Attributes[attributeName] = value;
                    }

                    break;
                case "boolean":
                    Boolean booleanValue;
                    if (Boolean.TryParse(value, out booleanValue))
                    {
                        if (!entity.Attributes.Contains(attributeName))
                        {
                            entity.Attributes.Add(attributeName, booleanValue);
                        }
                        else
                        {
                            entity.Attributes[attributeName] = booleanValue;
                        }
                    }

                    break;
                case "integer":
                    Int32 intValue;
                    if (Int32.TryParse(value, out intValue))
                    {
                        if (!entity.Attributes.Contains(attributeName))
                        {
                            entity.Attributes.Add(attributeName, intValue);
                        }
                        else
                        {
                            entity.Attributes[attributeName] = intValue;
                        }
                    }

                    break;
                case "decimal":
                    decimal decValue;
                    if (decimal.TryParse(value, out decValue))
                    {
                        if (!entity.Attributes.Contains(attributeName))
                        {
                            entity.Attributes.Add(attributeName, decValue);
                        }
                        else
                        {
                            entity.Attributes[attributeName] = decValue;
                        }
                    }

                    break;

                case "money":
                    decimal monValue;
                    if (decimal.TryParse(value, out monValue))
                    {
                        if (!entity.Attributes.Contains(attributeName))
                        {
                            entity.Attributes.Add(attributeName, new Money(monValue));
                        }
                        else
                        {
                            entity.Attributes[attributeName] = new Money(monValue);
                        }
                    }

                    break;
                case "double":
                    Double doubleValue;
                    if (Double.TryParse(value, out doubleValue))
                    {
                        if (!entity.Attributes.Contains(attributeName))
                        {
                            entity.Attributes.Add(attributeName, doubleValue);
                        }
                        else
                        {
                            entity.Attributes[attributeName] = doubleValue;
                        }
                    }

                    break;

                case "datetime":
                    DateTime dateValue;
                    if (DateTime.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateValue))
                    {
                        if (!entity.Attributes.Contains(attributeName))
                        {
                            entity.Attributes.Add(attributeName, dateValue);
                        }
                        else
                        {
                            entity.Attributes[attributeName] = dateValue;
                        }
                    }

                    break;
                case "lookup":
                    Guid guidValue;
                    if (Guid.TryParse(value, out guidValue))
                    {
                        if (!entity.Attributes.Contains(attributeName))
                        {
                            entity.Attributes.Add(attributeName, new EntityReference(lookupEntityName, guidValue));
                        }
                        else
                        {
                            entity.Attributes[attributeName] = new EntityReference(lookupEntityName, guidValue);
                        }
                    }

                    break;
                case "picklist":
                    Int32 optionSetValue;
                    if (Int32.TryParse(value, out optionSetValue))
                    {
                        if (!entity.Attributes.Contains(attributeName))
                        {
                            entity.Attributes.Add(attributeName, new OptionSetValue(optionSetValue));
                        }
                        else
                        {
                            entity.Attributes[attributeName] = new OptionSetValue(optionSetValue);
                        }
                    }

                    value = String.Empty;
                    break;
            }
        }

        public static void SetNullableValue(this Entity entity, string attributeName, string attributeType, string value, string lookupEntityName = null)
        {
            if (value.IsEmpty())
            {
                SetNullValue(entity, attributeName, attributeType);
                return;
            }

            switch (attributeType.ToLowerInvariant())
            {
                case "string":
                case "memo":
                    SetValue(entity, attributeName, value);
                    break;

                case "boolean":
                    if (value.ToNullableBool().HasValue)
                        SetValue(entity, attributeName, value.ToBool());
                    break;

                case "integer":
                    if (value.ToNullableInt().HasValue)
                        SetValue(entity, attributeName, value.ToInt());
                    break;

                case "decimal":
                    if (value.ToNullableDecimal().HasValue)
                        SetValue(entity, attributeName, value.ToDecimal());
                    break;

                case "money":
                    if (value.ToNullableDecimal().HasValue)
                    {
                        if (!entity.Attributes.Contains(attributeName))
                        {
                            entity.Attributes.Add(attributeName, new Money(value.ToDecimal()));
                        }
                        else
                        {
                            entity.Attributes[attributeName] = new Money(value.ToDecimal());
                        }
                    }
                    break;

                case "double":
                    if (value.ToNullableDouble().HasValue)
                        SetValue(entity, attributeName, value.ToNullableDouble().Value);
                    break;

                case "datetime":
                    if (value.ToDate().HasValue)
                        SetValue(entity, attributeName, value.ToDate().Value);
                    break;

                case "lookup":
                    if (value.ToGuid().HasValue && lookupEntityName.IsNotEmpty())
                    {
                        if (!entity.Attributes.Contains(attributeName))
                        {
                            entity.Attributes.Add(attributeName, new EntityReference(lookupEntityName, value.ToGuid().Value));
                        }
                        else
                        {
                            entity.Attributes[attributeName] = new EntityReference(lookupEntityName, value.ToGuid().Value);
                        }
                    }
                    break;

                case "picklist":
                    if (value.ToNullableInt().HasValue)
                    {
                        if (!entity.Attributes.Contains(attributeName))
                        {
                            entity.Attributes.Add(attributeName, new OptionSetValue(value.ToInt()));
                        }
                        else
                        {
                            entity.Attributes[attributeName] = new OptionSetValue(value.ToInt());
                        }
                    }
                    break;
                default:
                    break;
            }
        }        

        private static void SetNullValue(Entity entity, string attributeName, string attributeType)
        {
            switch (attributeType.ToLowerInvariant())
            {
                case "string":
                case "memo":
                case "boolean":
                case "integer":
                case "decimal":
                case "money":
                case "double":
                case "datetime":
                case "picklist":
                case "lookup":
                    SetValue(entity, attributeName, null);
                    break;
            }
        }

        private static void SetValue(Entity entity, string attributeName, object value)
        {
            if (!entity.Attributes.Contains(attributeName))
            {
                entity.Attributes.Add(attributeName, value);
            }
            else
            {
                entity.Attributes[attributeName] = value;
            }
        }

        public static bool IsEqual(this Entity entity, Entity compareTo)
        {
            foreach (var item in entity.Attributes)
            {
                if (!compareTo.Attributes.ContainsKey(item.Key))
                    return false;

                if (item.GetType().FullName == "Microsoft.Xrm.Sdk.OptionSetValue")
                {
                    var fromValue = item.Value as OptionSetValue;
                    var toValue = compareTo.Attributes[item.Key] as OptionSetValue;
                    if (fromValue.Value == toValue.Value)
                        continue;
                }

                if (!compareTo.Attributes[item.Key].Equals(item.Value))
                    return false;
            }

            return true;
        }

        /// <summary>
        /// Formatted Value of attribute
        /// </summary>
        /// <param name="entity">Entity</param>
        /// <param name="attributeName">Attribute Logical Name</param>
        /// <returns>Formatted Value of attribute</returns>
        public static string GetAttributeStringValue(this Entity entity, string attributeName)
        {
            var isAliasedValue = false;

            attributeName = attributeName.ToLower();

            var attribute = entity.Attributes.Where(x => x.Key.Equals(attributeName, StringComparison.InvariantCultureIgnoreCase)).Select(x => x.Value).FirstOrDefault();
            if (attribute == null)
                return string.Empty;

            var hasFormattedValue = entity.FormattedValues.Any(x => x.Key.Equals(attributeName, StringComparison.InvariantCultureIgnoreCase));
            var formattedValue = entity.FormattedValues.Where(x => x.Key.Equals(attributeName, StringComparison.InvariantCultureIgnoreCase)).Select(x => x.Value).FirstOrDefault();
            var allisedValue = new AliasedValue();
            if (attribute.GetType().ToString() == "Microsoft.Xrm.Sdk.AliasedValue")
            {
                allisedValue = attribute as AliasedValue;
                isAliasedValue = true;
            }

            switch (attribute.GetType().ToString())
            {
                case "System.DateTime":
                    if (hasFormattedValue)
                        return formattedValue;

                    if (isAliasedValue)
                    {
                        DateTime value;
                        return !DateTime.TryParse(attribute.ToString(), out value) ? "" : value.ToString();
                    }

                    return entity.GetDateTimeValue(attributeName).Value.ToString();

                case "Microsoft.Xrm.Sdk.OptionSetValue":
                    if (hasFormattedValue)
                        return formattedValue;

                    if (isAliasedValue)
                        return ((OptionSetValue)attribute).Value.ToString();

                    return entity.GetAttributeValue<OptionSetValue>(attributeName).Value.ToString();

                case "System.String":
                    if (isAliasedValue)
                        return allisedValue.Value.ToString();

                    return entity.GetAttributeValue<string>(attributeName);

                case "System.Boolean":
                    if (hasFormattedValue)
                        return formattedValue;

                    if (isAliasedValue)
                    {
                        bool value;
                        return !bool.TryParse(allisedValue.Value.ToString(), out value) ? "" : value.ToString();
                    }

                    return entity.GetAttributeValue<bool?>(attributeName).Value.ToString();

                case "System.Int32":
                    if (hasFormattedValue)
                        return formattedValue;

                    if (isAliasedValue)
                    {
                        int value;
                        return !int.TryParse(allisedValue.Value.ToString(), out value) ? "" : value.ToString();
                    }

                    return entity.GetAttributeValue<int?>(attributeName).Value.ToString();

                case "Microsoft.Xrm.Sdk.EntityReference":
                    if (hasFormattedValue)
                        return formattedValue;

                    if (isAliasedValue)
                        return ((EntityReference)attribute).Name;

                    return entity.GetAttributeValue<EntityReference>(attributeName).Name;

                case "System.Guid":
                    if (hasFormattedValue)
                        return formattedValue;

                    if (isAliasedValue)
                        return allisedValue.Value.ToString();

                    return entity.GetAttributeValue<Guid>(attributeName).ToString();
                case "Microsoft.Xrm.Sdk.Money":
                    if (hasFormattedValue)
                        return formattedValue;

                    if (isAliasedValue)
                        return ((Money)attribute).Value.ToString();

                    return entity.GetAttributeValue<Money>(attributeName).Value.ToString();
                case "Microsoft.Xrm.Sdk.EntityCollection":
                    try
                    {
                        var partyList = entity.GetAttributeValue<EntityCollection>(attributeName).Entities.Select(x => x.GetAttributeValue<EntityReference>("partyid").Name).ToList();
                        return string.Join(",", partyList);
                    }
                    catch (Exception ex)
                    {
                        TM.TraceError(ex, new StackTrace().GetFrame(0).GetMethod().Name, System.Reflection.Assembly.GetCallingAssembly().GetName().Name);
                        return string.Empty;
                    }
                default:
                    if (hasFormattedValue)
                        return formattedValue;
                    if (isAliasedValue)
                    {
                        if (allisedValue.Value.ToString() == "Microsoft.Xrm.Sdk.EntityReference")
                            return ((EntityReference)allisedValue.Value).Name;
                        return allisedValue.Value.ToString();
                    }

                    return entity.GetAttributeValue<string>(attributeName);
            }
        }

        /// <summary>
        /// Formatted Value of attribute
        /// </summary>
        /// <param name="entity">Entity</param>
        /// <param name="attributeName">Attribute Logical Name</param>
        /// <returns>Formatted Value of attribute</returns>
        public static T GetAttributeAliasOrValue<T>(this Entity entity, string attributeName)
        {
            var isAliasedValue = false;

            attributeName = attributeName.ToLower();
            var attribute = entity.Attributes.Where(x => x.Key.Equals(attributeName, StringComparison.InvariantCultureIgnoreCase)).Select(x => x.Value).FirstOrDefault();
            if (attribute == null)
                return default(T);

            var allisedValue = new AliasedValue();
            if (attribute.GetType().ToString() == "Microsoft.Xrm.Sdk.AliasedValue")
            {
                allisedValue = attribute as AliasedValue;
                isAliasedValue = true;
            }

            if (isAliasedValue)
            {
                switch (allisedValue.Value.GetType().ToString())
                {
                    case "System.DateTime":
                        return (T)allisedValue.Value;
                    case "System.Boolean":
                        return (T)allisedValue.Value;
                    case "System.Int32":
                        return (T)allisedValue.Value;
                    case "Microsoft.Xrm.Sdk.EntityReference":
                        return (T)allisedValue.Value;
                    case "System.Guid":
                        return (T)allisedValue.Value;
                    case "System.String":
                        return (T)allisedValue.Value;
                    case "Microsoft.Xrm.Sdk.OptionSetValue":
                        return (T)allisedValue.Value;
                    case "System.Decimal":
                        return (T)allisedValue.Value;
                    case "Microsoft.Xrm.Sdk.Money":
                        return (T)allisedValue.Value;
                }
            }
            else
            {
                return entity.GetAttributeValue<T>(attributeName);
            }

            return default(T);
        }

        /// <summary>
        /// Id Value of attribute
        /// Only valid for lookup, optionset
        /// </summary>
        /// <param name="entity">Entity</param>
        /// <param name="attributeName">Attribute Logical Name</param>
        /// <returns>Id Value of attribute</returns>
        public static string GetAttributeIdValue(this Entity entity, string attributeName)
        {
            var isAliasedValue = false;

            attributeName = attributeName.ToLower();

            if (!entity.Contains(attributeName))
                return string.Empty;

            var attribute = entity[attributeName];
            if (attribute.GetType().ToString() == "Microsoft.Xrm.Sdk.AliasedValue")
            {
                attribute = entity.GetAttributeValue<AliasedValue>(attributeName).Value;
                isAliasedValue = true;
            }

            switch (attribute.GetType().ToString())
            {
                case "Microsoft.Xrm.Sdk.OptionSetValue":
                    if (isAliasedValue)
                        return ((OptionSetValue)attribute).Value.ToString();

                    return entity.GetAttributeValue<OptionSetValue>(attributeName).Value.ToString();

                case "Microsoft.Xrm.Sdk.EntityReference":
                    if (isAliasedValue)
                        return ((EntityReference)attribute).Id.ToString();

                    return entity.GetAttributeValue<EntityReference>(attributeName).Id.ToString();

                case "System.Guid":
                    if (entity.FormattedValues.Contains(attributeName))
                        return entity.FormattedValues[attributeName];

                    if (isAliasedValue)
                        return attribute.ToString();

                    return entity.GetAttributeValue<Guid>(attributeName).ToString();

                default:
                    return string.Empty;
            }
        }

        public static string ResolveAttributeData(this Entity entity, string attributeName)
        {
            var isAliasedValue = false;

            attributeName = attributeName.ToLower();

            if (!entity.Contains(attributeName))
                return string.Empty;

            var attribute = entity[attributeName];
            if (attribute.GetType().ToString() == "Microsoft.Xrm.Sdk.AliasedValue")
            {
                attribute = entity.GetAttributeValue<AliasedValue>(attributeName).Value;
                isAliasedValue = true;
            }

            if (!IsValidAttribute(attributeName))
                return string.Empty;

            switch (attribute.GetType().ToString())
            {
                case "System.DateTime":

                    if (isAliasedValue)
                    {
                        DateTime value;
                        return !DateTime.TryParse(attribute.ToString(), out value) ? "" : value.ToString();
                    }

                    return entity.GetAttributeValue<DateTime?>(attributeName).Value.ToString();

                case "Microsoft.Xrm.Sdk.OptionSetValue":

                    if (isAliasedValue)
                        return ((OptionSetValue)attribute).Value.ToString();

                    return entity.GetAttributeValue<OptionSetValue>(attributeName).Value.ToString();

                case "System.String":
                    if (isAliasedValue)
                        return attribute.ToString();

                    return entity.GetAttributeValue<string>(attributeName);

                case "System.Boolean":

                    if (isAliasedValue)
                    {
                        bool value;
                        return !bool.TryParse(attribute.ToString(), out value) ? "" : value.ToString();
                    }

                    return entity.GetAttributeValue<bool?>(attributeName).Value.ToString();

                case "System.Int32":

                    if (isAliasedValue)
                    {
                        int value;
                        return !int.TryParse(attribute.ToString(), out value) ? "" : value.ToString();
                    }

                    return entity.GetAttributeValue<int?>(attributeName).Value.ToString();

                case "Microsoft.Xrm.Sdk.EntityReference":

                    if (isAliasedValue)
                        return ((EntityReference)attribute).Id.ToString();

                    return entity.GetAttributeValue<EntityReference>(attributeName).Id.ToString();

                case "System.Guid":

                    if (isAliasedValue)
                        return attribute.ToString();

                    return entity.GetAttributeValue<Guid>(attributeName).ToString();
                case "Microsoft.Xrm.Sdk.EntityCollection":
                    try
                    {
                        var partyList = entity.GetAttributeValue<EntityCollection>(attributeName).Entities.Select(x => x.GetAttributeValue<EntityReference>("partyid").Name).ToList();
                        return string.Join(",", partyList);
                    }
                    catch (Exception ex)
                    {
                        TM.TraceError(ex, new StackTrace().GetFrame(0).GetMethod().Name, System.Reflection.Assembly.GetCallingAssembly().GetName().Name);
                        return string.Empty;
                    }
                default:

                    return entity.GetAttributeValue<string>(attributeName);
            }
        }

        private static bool IsValidAttribute(string name)
        {
            switch (name)
            {
                case "createdon":
                case "createdby":
                case "ownerid":
                case "owningbusinessunit":
                case "statecode":
                case "statuscode":
                case "modifiedon":
                case "modifiedby":
                case "owninguser":
                case "organizationid":
                case "overriddencreatedon":
                case "importsequencenumber":
                case "timezoneruleversionnumber":
                    return false;
            }
            return true;
        }

        /// <summary>
        /// Allow entities to sort
        /// </summary>
        /// <param name="entity">Entity</param>
        /// <param name="otherEntity">Entity to Compare</param>
        /// <param name="attributeName">Attribute Logical Name</param>
        /// <returns>Compare attribute and return result</returns>
        public static int CompareTo(this Entity entity, Entity otherEntity, string attributeName)
        {
            attributeName = attributeName.ToLower();

            if (!entity.Contains(attributeName))
                return 0;

            if (!otherEntity.Contains(attributeName))
                return 0;

            var attribute = entity[attributeName];
            if (attribute.GetType().ToString() == "Microsoft.Xrm.Sdk.AliasedValue")
            {
                attribute = entity.GetAttributeValue<AliasedValue>(attributeName).Value;
            }

            return CompareTo(entity, otherEntity, attributeName, attribute);
        }

        /// <summary>
        /// Allow entities to sort
        /// </summary>
        /// <param name="entity">Entity</param>
        /// <param name="otherEntity">Entity to Compare</param>
        /// <param name="attributeName">Attribute Logical Name</param>
        /// <param name="attribute">Attribute</param>
        /// <returns>Compare attribute and return result</returns>
        private static int CompareTo(Entity entity, Entity otherEntity, string attributeName, object attribute)
        {
            attributeName = attributeName.ToLower();
            switch (attribute.GetType().ToString())
            {
                case "System.DateTime":
                    return entity.GetAttributeValue<DateTime?>(attributeName).Value.CompareTo(otherEntity.GetAttributeValue<DateTime?>(attributeName).Value);
                case "Microsoft.Xrm.Sdk.OptionSetValue":
                    return entity.GetAttributeValue<OptionSetValue>(attributeName).Value.CompareTo(otherEntity.GetAttributeValue<OptionSetValue>(attributeName).Value);
                case "System.String":
                    return entity.GetAttributeValue<string>(attributeName).CompareTo(otherEntity.GetAttributeValue<string>(attributeName));
                case "System.Boolean":
                    return entity.GetAttributeValue<bool?>(attributeName).Value.CompareTo(otherEntity.GetAttributeValue<bool?>(attributeName).Value);
                case "System.Int32":
                    return entity.GetAttributeValue<int?>(attributeName).Value.CompareTo(otherEntity.GetAttributeValue<int?>(attributeName).Value);
                case "Microsoft.Xrm.Sdk.EntityReference":
                    return entity.GetAttributeValue<EntityReference>(attributeName).Name.CompareTo(otherEntity.GetAttributeValue<EntityReference>(attributeName).Name);
            }

            return 0;
        }

        public static int GetOptionSetValue(this Entity entity, string attributeName)
        {
            if (!entity.Contains(attributeName))
                return 0;

            return entity.GetAttributeAliasOrValue<OptionSetValue>(attributeName).Value;
        }

        public static string GetOptionSetLabel(this Entity entity, string attributeName)
        {
            if (!entity.Contains(attributeName) || (entity.FormattedValues != null && !entity.FormattedValues.ContainsKey(attributeName)))
                return string.Empty;

            return entity.FormattedValues[attributeName];
        }

        public static string GetStringValue(this Entity entity, string attributeName)
        {
            if (!entity.Contains(attributeName))
                return string.Empty;

            return entity.GetAttributeAliasOrValue<string>(attributeName);
        }

        public static bool GetBooleanValue(this Entity entity, string attributeName)
        {
            if (!entity.Contains(attributeName))
                return false;

            return entity.GetAttributeAliasOrValue<bool?>(attributeName).GetValueOrDefault(false);
        }

        public static bool? GetNullableBooleanValue(this Entity entity, string attributeName)
        {
            if (!entity.Contains(attributeName))
                return null;

            return entity.GetAttributeAliasOrValue<bool?>(attributeName);
        }

        public static string GetDecimalStringValue(this Entity entity, string attributeName)
        {
            if (entity == null || !entity.Contains(attributeName))
                return string.Empty;

            return entity.GetAttributeAliasOrValue<decimal?>(attributeName).HasValue ? entity.GetAttributeValue<decimal?>(attributeName).Value.ToString() : string.Empty;
        }

        public static Guid? GetLookupId(this Entity entity, string attributeName)
        {
            try
            {
                if (entity==null || !entity.Contains(attributeName))
                    return default(Guid?);

                var entityReference = entity.GetAttributeAliasOrValue<EntityReference>(attributeName);
                if (entityReference == null)
                    return default(Guid?);

                return entityReference.Id;
            }
            catch(NullReferenceException)
            {
                throw new Exception("Error retrieving attribute value for " + attributeName);
            }
            catch (Exception ex)
            {                
                throw ex;
            }            
        }

        public static string GetLookupIdString(this Entity entity, string attributeName)
        {
            try
            {
                if (entity == null || !entity.Contains(attributeName))
                    return string.Empty;

                var entityReference = entity.GetAttributeAliasOrValue<EntityReference>(attributeName);
                if (entityReference == null)
                    return string.Empty;

                return entityReference.Id.ToString();
            }
            catch(NullReferenceException)
            {
                throw new Exception("Error retrieving attribute value for " + attributeName);
            }
            catch (Exception ex)
            {                
                throw ex;
            }
        }

        /// <summary>
        /// Return lookup text
        /// </summary>
        /// <param name="entity">Entity</param>
        /// <param name="attributeName">Name of the attribute</param>
        /// <returns>string</returns>
        public static string GetLookupName(this Entity entity, string attributeName, Entity entityImage = null)
        {
            if (entity != null && entity.Contains(attributeName))
            {
                var value = entity.GetAttributeAliasOrValue<EntityReference>(attributeName);
                return value != null ? value.Name : string.Empty;
            }

            if (entityImage != null && entityImage.Contains(attributeName))
            {
                var value = entityImage.GetAttributeAliasOrValue<EntityReference>(attributeName);
                return value != null ? value.Name : string.Empty;
            }

            return string.Empty;
        }

        public static string GetLookupEntityName(this Entity entity, string attributeName)
        {
            return GetLookupEntityName(entity, attributeName, null);
        }

        public static string GetLookupEntityName(this Entity entity, string attributeName, Entity entityImage)
        {
            if (entity.Contains(attributeName))
            {
                return entity.GetAttributeValue<EntityReference>(attributeName).LogicalName;
            }

            if (entityImage != null && entityImage.Contains(attributeName))
            {
                return entityImage.GetAttributeValue<EntityReference>(attributeName).LogicalName;
            }

            return string.Empty;
        }

        public static string GetNumericStringValue(this Entity entity, string attributeName)
        {
            if (!entity.Contains(attributeName))
                return string.Empty;

            return entity.GetAttributeValue<int?>(attributeName).HasValue ? entity.GetAttributeValue<int?>(attributeName).Value.ToString() : string.Empty;
        }

        public static int GetNumericValue(this Entity entity, string attributeName)
        {
            if (!entity.Contains(attributeName))
                return 0;

            return entity.GetAttributeValue<int?>(attributeName).HasValue ? entity.GetAttributeValue<int?>(attributeName).Value : 0;
        }

        public static decimal GetDecimalValue(this Entity entity, string attributeName)
        {
            if (!entity.Contains(attributeName))
                return 0;

            return entity.GetAttributeValue<decimal?>(attributeName).HasValue ? entity.GetAttributeValue<decimal?>(attributeName).Value : 0;
        }

        public static decimal GetCurrencyValue(this Entity entity, string attributeName)
        {
            if (!entity.Contains(attributeName))
                return 0;

            var attr = entity.GetAttributeValue<Money>(attributeName);

            if (attr == null)
                return 0;

            return attr.Value;
        }

        public static string GetDateStringValue(this Entity entity, string attributeName, string shortDatePattern, string timeZoneName)
        {
            if (!entity.Contains(attributeName))
                return string.Empty;

            var dateValue = entity.GetAttributeAliasOrValue<DateTime?>(attributeName);
            if (!dateValue.HasValue)
                return string.Empty;

            var date = DateHelper.ConvertTimeFromUTCbyTimeZone(dateValue.Value, timeZoneName);
            return date.ToString(shortDatePattern, CultureInfo.InvariantCulture);
        }

        public static string GetDateTimeStringValue(this Entity entity, string attributeName, string fullDateTimePattern, string timeZoneName)
        {
            if (!entity.Contains(attributeName))
                return string.Empty;

            if (!entity.GetAttributeValue<DateTime?>(attributeName).HasValue)
                return string.Empty;

            var date = DateHelper.ConvertTimeFromUTCbyTimeZone(entity.GetAttributeValue<DateTime>(attributeName), timeZoneName);
            return date.ToString(fullDateTimePattern, CultureInfo.InvariantCulture);
        }

        public static string GetTimeStringValue(this Entity entity, string attributeName, string timeFormat, string timeZoneName)
        {
            if (!entity.Contains(attributeName))
                return string.Empty;

            if (!entity.GetAttributeValue<DateTime?>(attributeName).HasValue)
                return string.Empty;

            var date = DateHelper.ConvertTimeFromUTCbyTimeZone(entity.GetAttributeValue<DateTime>(attributeName), timeZoneName);
            return date.ToString(timeFormat, CultureInfo.InvariantCulture);
        }

        public static EntityData ToEntityData(this Entity src)
        {
            var entityData = new EntityData
            {
                Id = src.Id,
                EntityLogicalName = src.LogicalName,
                PrimaryKeyFieldName = "", //TODO: need to find a way to retrieve this fiels data
            };

            ResolveAttributeData(ref entityData, src);
            return entityData;
        }

        public static EntityData ToEntityDataWithLinkedRecords(this Entity src)
        {
            var entityData = new EntityData
            {
                Id = src.Id,
                EntityLogicalName = src.LogicalName,
                PrimaryKeyFieldName = "", //TODO: need to find a way to retrieve this fiels data
            };

            ResolveAttributeDataWithLinkedRecords(ref entityData, src);
            return entityData;
        }

        public static EntityData ToEntityStringData(this Entity src)
        {
            var entityData = new EntityData
            {
                Id = src.Id,
                EntityLogicalName = src.LogicalName,
                PrimaryKeyFieldName = "", //TODO: need to find a way to retrieve this fiels data
            };

            ResolveAttributeStringData(ref entityData, src);
            return entityData;
        }

        private static void ResolveAttributeStringData(ref EntityData target, Entity crmEntity)
        {
            var attributes = new List<AttributeData>();
            foreach (var item in crmEntity.Attributes)
            {
                object obj = null;

                if (item.Value.GetType().ToString() == "Microsoft.Xrm.Sdk.AliasedValue")
                {
                    obj = ((AliasedValue)item.Value).Value;
                }
                else
                {
                    obj = item.Value;
                }

                switch (obj.GetType().ToString())
                {
                    case "System.Guid":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.Guid,
                            Value = GetAttributeStringValue(crmEntity, item.Key)
                        });
                        break;
                    case "System.DateTime":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.DateTime,
                            Value = GetAttributeStringValue(crmEntity, item.Key)
                        });
                        break;
                    case "Microsoft.Xrm.Sdk.OptionSetValue":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.OptionSetValue,
                            Value = GetAttributeStringValue(crmEntity, item.Key)
                        });
                        break;
                    case "System.String":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.String,
                            Value = GetAttributeStringValue(crmEntity, item.Key)
                        });
                        break;
                    case "System.Boolean":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.Boolean,
                            Value = GetAttributeStringValue(crmEntity, item.Key)
                        });
                        break;
                    case "System.Int32":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.Int32,
                            Value = GetAttributeStringValue(crmEntity, item.Key)
                        });
                        break;
                    case "System.Decimal":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.Decimal,
                            Value = GetAttributeStringValue(crmEntity, item.Key)
                        });
                        break;
                    case "Microsoft.Xrm.Sdk.EntityReference":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.EntityReference,
                            Value = GetAttributeStringValue(crmEntity, item.Key)
                        });
                        break;
                    default:
                        break;
                }
            }

            target.AttributeDataList = attributes;
        }

        private static void ResolveAttributeData(ref EntityData target, Entity crmEntity)
        {
            var attributes = new List<AttributeData>();
            foreach (var item in crmEntity.Attributes)
            {
                switch (item.Value.GetType().ToString())
                {
                    case "System.Guid":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.Guid,
                            Value = item.Value.ToString()
                        });
                        break;
                    case "System.DateTime":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.DateTime,
                            Value = ((DateTime)item.Value).ToString()
                        });
                        break;
                    case "Microsoft.Xrm.Sdk.OptionSetValue":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.OptionSetValue,
                            Value = ((OptionSetValue)item.Value).Value.ToString()
                        });
                        break;
                    case "System.String":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.String,
                            Value = (string)item.Value
                        });
                        break;
                    case "System.Boolean":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.Boolean,
                            Value = ((Boolean)item.Value).ToString()
                        });
                        break;
                    case "System.Int32":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.Int32,
                            Value = ((int)item.Value).ToString()
                        });
                        break;
                    case "System.Decimal":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.Decimal,
                            Value = ((decimal)item.Value).ToString()
                        });
                        break;
                    case "Microsoft.Xrm.Sdk.EntityReference":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.EntityReference,
                            Value = ((EntityReference)item.Value).Id.ToString(),
                            NameValue = ((EntityReference)item.Value).Name,
                            LookupEntityName = ((EntityReference)item.Value).LogicalName
                        });
                        break;
                    default:
                        break;
                }
            }

            target.AttributeDataList = attributes;
        }

        private static void ResolveAttributeDataWithLinkedRecords(ref EntityData target, Entity crmEntity)
        {
            var attributes = new List<AttributeData>();
            foreach (var item in crmEntity.Attributes)
            {
                object obj = null;

                if (item.Value.GetType().ToString() == "Microsoft.Xrm.Sdk.AliasedValue")
                {
                    obj = ((AliasedValue)item.Value).Value;
                }
                else
                {
                    obj = item.Value;
                }

                switch (obj.GetType().ToString())
                {
                    case "System.Guid":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.Guid,
                            NameValue = GetAttributeStringValue(crmEntity, item.Key),
                            Value = GetAttributeAliasOrValue<Guid>(crmEntity, item.Key).ToString()
                        });
                        break;
                    case "System.DateTime":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.DateTime,
                            NameValue = GetAttributeStringValue(crmEntity, item.Key),
                            Value = GetAttributeAliasOrValue<DateTime>(crmEntity, item.Key).RemoveDaylightSavings().ToString()
                        });
                        break;
                    case "Microsoft.Xrm.Sdk.OptionSetValue":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.OptionSetValue,
                            NameValue = GetAttributeStringValue(crmEntity, item.Key),
                            Value = GetAttributeAliasOrValue<OptionSetValue>(crmEntity, item.Key).Value.ToString()
                        });
                        break;
                    case "System.String":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.String,
                            NameValue = GetAttributeStringValue(crmEntity, item.Key),
                            Value = GetAttributeAliasOrValue<string>(crmEntity, item.Key).ToString()
                        });
                        break;
                    case "System.Boolean":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.Boolean,
                            NameValue = GetAttributeStringValue(crmEntity, item.Key),
                            Value = GetAttributeAliasOrValue<bool>(crmEntity, item.Key).ToString()
                        });
                        break;
                    case "System.Int32":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.Int32,
                            NameValue = GetAttributeStringValue(crmEntity, item.Key),
                            Value = GetAttributeAliasOrValue<int>(crmEntity, item.Key).ToString()
                        });
                        break;
                    case "System.Decimal":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.Decimal,
                            NameValue = GetAttributeStringValue(crmEntity, item.Key),
                            Value = GetAttributeAliasOrValue<decimal>(crmEntity, item.Key).ToString()
                        });
                        break;
                    case "Microsoft.Xrm.Sdk.EntityReference":
                        var value = GetAttributeAliasOrValue<EntityReference>(crmEntity, item.Key);
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.EntityReference,
                            Value = value.Id.ToString(),
                            NameValue = value.Name,
                            LookupEntityName = value.LogicalName
                        });
                        break;
                    case "Microsoft.Xrm.Sdk.Money":
                        attributes.Add(new AttributeData
                        {
                            Name = item.Key,
                            AttributeType = AttributeType.Decimal,
                            NameValue = GetAttributeStringValue(crmEntity, item.Key),
                            Value = GetAttributeAliasOrValue<Money>(crmEntity, item.Key).ToString()
                        });
                        break;                                                
                    default:
                        break;
                }
            }

            target.AttributeDataList = attributes;
        }

        public static bool GetBoolValue(this Entity entity, string attName, Entity entityImage = null)
        {
            if (entity.Contains(attName))
            {
                return entity.GetAttributeAliasOrValue<bool?>(attName).GetValueOrDefault();
            }

            if (entityImage != null && entityImage.Contains(attName))
            {
                return entityImage.GetAttributeAliasOrValue<bool?>(attName).GetValueOrDefault();
            }
            return false;
        }

        public static string GetStringValue(this Entity entity, string attName, Entity entityImage = null)
        {
            if (entity.Contains(attName))
            {
                return entity.GetAttributeValue<string>(attName);
            }

            if (entityImage != null && entityImage.Contains(attName))
            {
                return entityImage.GetAttributeValue<string>(attName);
            }
            return string.Empty;
        }

        public static Guid? GetLookupId(this Entity entity, string attName, Entity entityImage = null)
        {
            if (entity.Contains(attName))
            {
                var value = entity.GetAttributeValue<EntityReference>(attName);
                return value != null ? value.Id : default(Guid?);
            }

            if (entityImage != null && entityImage.Contains(attName))
            {
                var value = entityImage.GetAttributeValue<EntityReference>(attName);
                return value != null ? value.Id : default(Guid?);
            }

            return default(Guid?);
        }

        public static string GetLookupText(this Entity entity, string attName, Entity entityImage = null)
        {
            if (entity.Contains(attName))
            {
                var value = entity.GetAttributeValue<EntityReference>(attName);
                return value != null ? value.Name : string.Empty;
            }

            if (entityImage != null && entityImage.Contains(attName))
            {
                var value = entityImage.GetAttributeValue<EntityReference>(attName);
                return value != null ? value.Name : string.Empty;
            }

            return string.Empty;
        }

        public static int GetPicklistValue(this Entity entity, string attName, Entity entityImage = null)
        {
            if (entity.Contains(attName))
            {
                var value = entity.GetAttributeValue<OptionSetValue>(attName);
                return value != null ? value.Value : 0;
            }

            if (entityImage != null && entityImage.Contains(attName))
            {
                var value = entityImage.GetAttributeValue<OptionSetValue>(attName);
                return value != null ? value.Value : 0;
            }

            return 0;
        }

        public static int? GetNullablePicklistValue(this Entity entity, string attName, Entity entityImage = null)
        {
            if (entity.Contains(attName))
            {
                var value = entity.GetAttributeValue<OptionSetValue>(attName);
                return value != null ? value.Value : default(int?);
            }

            if (entityImage != null && entityImage.Contains(attName))
            {
                var value = entityImage.GetAttributeValue<OptionSetValue>(attName);
                return value != null ? value.Value : default(int?);
            }

            return default(int?);
        }

        public static decimal GetDecimalValue(this Entity entity, string attName, Entity entityImage)
        {
            if (entity.Contains(attName))
            {
                return entity.GetAttributeValue<decimal?>(attName).GetValueOrDefault();
            }

            if (entityImage != null && entityImage.Contains(attName))
            {
                return entityImage.GetAttributeValue<decimal?>(attName).GetValueOrDefault();
          
            }

            return 0;
        }

        public static DateTime? GetDateTimeValue(this Entity entity, string attName, Entity entityImage = null)
        {
            if (entity.Contains(attName))
            {
                var value = entity.GetAttributeAliasOrValue<DateTime?>(attName);
                return value.HasValue ? value.Value.RemoveDaylightSavings() : default(DateTime?);
            }

            if (entityImage != null && entityImage.Contains(attName))
            {
                var value = entityImage.GetAttributeAliasOrValue<DateTime?>(attName);
                return value.HasValue ? value.Value.RemoveDaylightSavings() : default(DateTime?);
            }

            return null;
        }

        public static DateTime? GetDateTimeUtcValue(this Entity entity, string attName, Entity entityImage = null)
        {
            if (entity.Contains(attName))
            {
                var value = entity.GetAttributeValue<DateTime?>(attName);
                return value.HasValue ? value.Value : default(DateTime?);
            }

            if (entityImage != null && entityImage.Contains(attName))
            {
                var value = entityImage.GetAttributeValue<DateTime?>(attName);
                return value.HasValue ? value.Value : default(DateTime?);
            }

            return null;
        }

        public static int? GetIntValue(this Entity entity, string attName, Entity entityImage = null)
        {
            if (entity.Contains(attName))
            {
                return entity.GetAttributeAliasOrValue<int?>(attName);
            }

            if (entityImage != null && entityImage.Contains(attName))
            {
                return entityImage.GetAttributeAliasOrValue<int?>(attName).GetValueOrDefault();
            }
            return null;
        }

        public static T GetAttributeValue<T>(this Entity entity, string attributeLogicalName, Entity entityImage)
        {
            return entity.GetAttributeValue<T>(attributeLogicalName, entityImage, default(T));
        }

        public static T GetAttributeValue<T>(this Entity entity, string attributeLogicalName, Entity entityImage, T defaultValue)
        {
            if (entity.Contains(attributeLogicalName))
            {
                return entity.GetAttributeValue<T>(attributeLogicalName);
            }
            else if (entityImage != null && entityImage.Contains(attributeLogicalName))
            {
                return entityImage.GetAttributeValue<T>(attributeLogicalName);
            }
            return defaultValue;
        }
    }