public ResultData Run(StepStartData data) { try { IOrganizationService serviceProxy = GetServiceProxy(); Entity entity = new Entity(CRMEntity.CRMEntityName); if (data.Data.ContainsKey(CRMEntity.CRMEntityDisplayName)) { Type type = GetMSCRMType(); object obj = data.Data[CRMEntity.CRMEntityDisplayName]; Dictionary <string, object> objDict = (Dictionary <string, object>)type.GetProperty("Fields").GetValue(obj); foreach (var field in CRMEntity.CRMEntityFields) { if (field.IsValidForUpdate == true) { if (field.IsRequired && !objDict.ContainsKey(field.FieldName)) { // Required fields must be present. If not, try to give a useful error message by listing all of the missing fields: IEnumerable <string> missingFields = CRMEntity.CRMEntityFields .Where(f => f.IsValidForUpdate == true && f.IsRequired && !objDict.ContainsKey(f.FieldName)) .Select(f => f.FieldName); string allMissing = string.Join(", ", missingFields); return(new ResultData(PATH_ERROR, new KeyValuePair <string, object>[] { new KeyValuePair <string, object>("Error Message", string.Format("The following required fields are missing: {0}.", allMissing)) })); } object fieldValue; if (!objDict.TryGetValue(field.FieldName, out fieldValue)) { // If this field doesn't exist on the update obj, skip it. continue; } if (fieldValue == null) { entity[field.FieldName] = null; } else { if (field.AttributeType == AttributeTypeCode.Money.ToString()) { decimal decimalValue = (decimal)fieldValue; entity[field.FieldName] = new Money(decimalValue); } else if (field.AttributeType == AttributeTypeCode.Picklist.ToString()) { int?optionValue = field.CRMOptionSet.FirstOrDefault(t => t.OptionName == fieldValue.ToString())?.OptionValue; if (optionValue != null) { entity[field.FieldName] = new OptionSetValue(optionValue.GetValueOrDefault()); } } else if (field.AttributeType == AttributeTypeCode.Customer.ToString() || field.AttributeType == AttributeTypeCode.Lookup.ToString()) { CRM2011LookUpTypeField lookUpFieldValue = fieldValue as CRM2011LookUpTypeField; if (lookUpFieldValue != null && string.IsNullOrEmpty(lookUpFieldValue.LookUpEntityName) == false && string.IsNullOrEmpty(lookUpFieldValue.Id) == false) { entity[field.FieldName] = new EntityReference(lookUpFieldValue.LookUpEntityName, new Guid(lookUpFieldValue.Id)); } } else { entity[field.FieldName] = fieldValue; } } } } } Guid guid = serviceProxy.Create(entity); return(new ResultData(PATH_SUCCESS, new DataPair[] { new DataPair(string.Format("Added {0} Id", CRMEntity.CRMEntityDisplayName), guid.ToString()) })); } catch (Exception ex) { return(new ResultData(PATH_ERROR, new KeyValuePair <string, object>[] { new KeyValuePair <string, object>("Error Message", ex.Message) })); } }
public object CreateObjectFromAttributes(Type type, AttributeCollection attributes) { var obj = Activator.CreateInstance(type); foreach (var attribute in attributes) { PropertyInfo pinfo = type.GetProperty(attribute.Key); if (pinfo != null) { object attributeValueObj; if (attribute.Value is OptionSetValue) { int i = ((OptionSetValue)attribute.Value).Value; Type enumType = pinfo.PropertyType.IsNullable() ? Nullable.GetUnderlyingType(pinfo.PropertyType) : pinfo.PropertyType; attributeValueObj = Enum.ToObject(enumType, i); } else if (attribute.Value is Money) { attributeValueObj = ((Money)attribute.Value).Value; } else if (attribute.Value is EntityReference) { EntityReference lookFieldValue = attribute.Value as EntityReference; attributeValueObj = new CRM2011LookUpTypeField() { LookUpEntityName = lookFieldValue.LogicalName, Id = lookFieldValue.Id.ToString() }; } else { attributeValueObj = attribute.Value; } pinfo.SetValue(obj, attributeValueObj); // Then wrap it in Nullable<> if necessary: /*object propValueObj; * * if (pinfo.PropertyType.IsNullable()) * { * propValueObj = Activator.CreateInstance(pinfo.PropertyType); * PropertyInfo pinfoValue = pinfo.PropertyType.GetProperty("Value"); * pinfoValue.SetValue(propValueObj, attributeValueObj); * } * else * { * propValueObj = attributeValueObj; * } * * pinfo.SetValue(obj, propValueObj);*/ /*object valueObj; * if (type.IsNullable()) { * Type nullableType = typeof(Nullable<>).MakeGenericType(type); * valueObj = Activator.CreateInstance(nullableType); * PropertyInfo pinfoValue = nullableType.GetProperty("Value"); * } * if (attribute.Value is OptionSetValue) { * Enum.ToObject * pinfo.SetValue(obj, (type)((OptionSetValue)attribute.Value).Value); * } * else if (attribute.Value is Money) { * pinfo.SetValue(obj, ((Money)attribute.Value).Value); * } * else if (attribute.Value is EntityReference) * { * EntityReference lookFieldValue = attribute.Value as EntityReference; * pinfo.SetValue(obj, new CRMLookUpTypeField() { LookUpEntityName = lookFieldValue.LogicalName, Id = lookFieldValue.Id.ToString() }); * } * else { * pinfo.SetValue(obj, attribute.Value); * } * pinfo.SetValue(obj, valueObj);*/ } } return(obj); }
public ResultData Run(StepStartData data) { try { if (data.Data.ContainsKey(ENTITY_ID)) { string entityId = data.Data[ENTITY_ID] as string; IOrganizationService serviceProxy = GetServiceProxy(); Entity entity = new Entity(CRMEntity.CRMEntityName); entity.Id = new Guid(entityId); if (data.Data.ContainsKey(CRMEntity.CRMEntityDisplayName)) { Type type = GetMSCRMType(); object obj = data.Data[CRMEntity.CRMEntityDisplayName]; Dictionary <string, object> objDict = (Dictionary <string, object>)type.GetProperty("Fields").GetValue(obj); Type objType = obj.GetType(); CRMEntity.LogCrmEntityFields("UpdateStep"); foreach (var field in CRMEntity.CRMEntityFields) { if (field.IsValidForUpdate == true) { object fieldValue; if (!objDict.TryGetValue(field.FieldName, out fieldValue)) { // If this field doesn't exist on the update obj, skip it. log.Debug($"Field '{field.FieldName}' is not being updated (no new value supplied)."); continue; } if (TreatEmptyStringAsNull) { string fieldValueStr = fieldValue as string; if (fieldValueStr != null && fieldValueStr.Length == 0) { log.Debug($"Empty string '{field.FieldName}' is being treated as null."); fieldValue = null; } } if (fieldValue == null) { // If this option is set, don't add null values. if (!TreatNullAsIgnore) { entity[field.FieldName] = null; } if (TreatNullAsIgnore) { log.Debug($"Null field '{field.FieldName}' is being ignored."); } else { log.Debug($"Null field '{field.FieldName}' updated normally."); } } else { if (field.AttributeType == AttributeTypeCode.Money.ToString()) { decimal decimalValue = (decimal)fieldValue; entity[field.FieldName] = new Money(decimalValue); log.Debug($"Field '{field.FieldName}[Money/decimal]' updated normally."); } else if (field.AttributeType == AttributeTypeCode.Picklist.ToString()) { int?optionValue = field.CRMOptionSet.FirstOrDefault(t => t.OptionName == fieldValue.ToString())?.OptionValue; if (optionValue != null) { entity[field.FieldName] = new OptionSetValue(optionValue.GetValueOrDefault()); log.Debug($"Field '{field.FieldName}[OptionSet]' updated normally."); } else { log.Debug($"Value '{fieldValue.ToString()}' not found in optionset, checking enum type directly."); string enumTypeName = $"{CRMEntity.GetFullTypeName()}_{field.FieldName}"; Type enumType = TypeUtilities.FindTypeByFullName(enumTypeName); if (enumType != null) { bool enumFound = false; try { if (Enum.IsDefined(enumType, fieldValue)) { // Enum.Parse should return an object with the string representation instead of int: object enumObj = Enum.Parse(enumType, fieldValue.ToString(), true); enumFound = true; // Then, find the Description of the enum, because this is what will actually match the dropdown list. FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString()); DescriptionAttribute[] attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); string enumDisplayName = null; if (attributes.Length > 0) { enumDisplayName = attributes[0].Description; } optionValue = field.CRMOptionSet.FirstOrDefault(t => t.OptionName == enumDisplayName)?.OptionValue; if (optionValue != null) { entity[field.FieldName] = new OptionSetValue(optionValue.GetValueOrDefault()); log.Debug($"Field '{field.FieldName}[OptionSet]' updated normally."); } else { log.Debug($"Field '{field.FieldName}[OptionSet]' not updated: null OptionValue, or no option found matching name '{enumDisplayName}'."); } } } catch { // Enum not found... } finally { if (!enumFound && log.IsDebugEnabled) { log.Debug($"Field '{field.FieldName}' not updated: optionset value '{fieldValue.ToString()}' not found in optionset " + $"({string.Join(", ", field.CRMOptionSet.Select(x => x.OptionName))})" + $" or in enum type '{enumTypeName}'."); } } } else { if (log.IsDebugEnabled) { log.Debug($"Field '{field.FieldName}' not updated: optionset value '{fieldValue.ToString()}' not found in optionset " + $"({string.Join(", ", field.CRMOptionSet.Select(x => x.OptionName))})" + " and enum type was not found."); } } } } else if (field.AttributeType == AttributeTypeCode.Customer.ToString() || field.AttributeType == AttributeTypeCode.Lookup.ToString()) { CRM2011LookUpTypeField lookUpFieldValue = fieldValue as CRM2011LookUpTypeField; if (lookUpFieldValue != null && string.IsNullOrEmpty(lookUpFieldValue.LookUpEntityName) == false && string.IsNullOrEmpty(lookUpFieldValue.Id) == false) { entity[field.FieldName] = new EntityReference(lookUpFieldValue.LookUpEntityName, new Guid(lookUpFieldValue.Id)); log.Debug($"Field '{field.FieldName}[Lookup]' updated normally."); } else { log.Debug($"Field '{field.FieldName}' not updated: lookup field value not found."); } } else { entity[field.FieldName] = fieldValue; log.Debug($"Field '{field.FieldName}' updated normally."); } } } else { log.Debug($"Skipping field '{field.FieldName}', not valid for update."); } } } serviceProxy.Update(entity); return(new ResultData(PATH_SUCCESS)); } else { return(new ResultData(PATH_ERROR, new KeyValuePair <string, object>[] { new KeyValuePair <string, object>("Error Message", "Entity Id cannot be null.") })); } } catch (Exception ex) { return(new ResultData(PATH_ERROR, new KeyValuePair <string, object>[] { new KeyValuePair <string, object>("Error Message", ex.Message) })); } }