private static string MapAttributesToJsonTemplate(Microsoft.Xrm.Sdk.Entity record, string jsonTemplate, string orgUrl, bool doHyperlinks = true, bool doLinksAsAdaptive = true) { try { if (!string.IsNullOrEmpty(jsonTemplate)) { foreach (KeyValuePair <string, object> kvp in record.Attributes) { if (!jsonTemplate.Contains("{" + kvp.Key + "}")) { // move to next element if not detected within the template continue; } string type = kvp.Value.GetType().Name.ToLower(); string value = kvp.Value.ToString(); string hyperlink = string.Empty; switch (type) { case ("entityreference"): { Microsoft.Xrm.Sdk.EntityReference refVal = (Microsoft.Xrm.Sdk.EntityReference)kvp.Value; value = refVal.Name; if (doHyperlinks) { hyperlink = orgUrl + "/main.aspx?forceUCI=1&etn=" + refVal.LogicalName + "&id=" + refVal.Id + "&pagetype=entityrecord"; } break; } case ("optionsetvalue"): { value = record.GetValueDisplayString(kvp.Key); break; } case ("datetime"): { DateTime dtVal = (DateTime)kvp.Value; value = dtVal.ToString("dd/MM/yyyy"); break; } case ("money"): { Money mVal = (Money)kvp.Value; value = mVal.Value.ToString("#,###,##0"); break; } case ("entitycollection"): { if (kvp.Value != null) { Microsoft.Xrm.Sdk.EntityCollection collection = (Microsoft.Xrm.Sdk.EntityCollection)kvp.Value; value = collection.ToCommaSeparatedString(); } else { value = "None"; } break; } default: { object o = kvp.Value; if (o != null) { value = o.ToString(); } else { value = ""; } break; } } if (!String.IsNullOrEmpty(hyperlink)) { if (doLinksAsAdaptive) { // In AdaptiveCards, Links are formatted as [caption](url link) jsonTemplate = jsonTemplate.Replace("{" + kvp.Key.ToLower() + "}", "[" + value + "](" + hyperlink + ")"); } else { jsonTemplate = jsonTemplate.Replace("{" + kvp.Key.ToLower() + "}", hyperlink); } } else { jsonTemplate = jsonTemplate.Replace("{" + kvp.Key.ToLower() + "}", value); } if (orgUrl != null) { jsonTemplate = jsonTemplate.Replace("{recordurl}", orgUrl + "/main.aspx?" + "etn=" + record.LogicalName + "&id=%7B" + record.Id + "%7D" + "&pagetype=entityrecord" + "&forceUCI=1"); } } // final step - remove all occuring strings by "{ and }" - effectively blanking the unmapped schemas string result = jsonTemplate; while (true) { int indexOfOpen = result.IndexOf("\"{"); int indexOfClose = result.IndexOf("}\"", indexOfOpen + 1); if (indexOfOpen < 0 && indexOfClose < 0) { break; } result = result.Substring(0, indexOfOpen) + "\"" + result.Substring(indexOfClose + 1); } if (result != jsonTemplate) { jsonTemplate = result; } } return(jsonTemplate); } catch (Exception e) { throw new Exception("SS21.Examples.TeamBot.AdaptiveCardFactory.MapAttributesToJsonTemplate :: ERROR :: Unable to map attributes to JSON template due to the following reason/s " + Environment.NewLine + e.Message); } }
public static string ProcessDynamicContent(Microsoft.Xrm.Sdk.Entity record, string jsonTemplate) { try { JObject jobject = JObject.Parse(jsonTemplate); JArray a = JArray.Parse(jobject["body"].ToString()); JArray newArray = new JArray(); foreach (JObject o in a.Children <JObject>()) { bool dynamicContent = false; string schemaName = string.Empty; foreach (JProperty p in o.Properties()) { if (p.Name.Equals("dynamicContent")) { dynamicContent = true; } if (p.Name.Equals("text")) { // extract schema name between { } ex. {description} // schemaName = description schemaName = (string)o["text"]; if (!string.IsNullOrEmpty(schemaName)) { schemaName = schemaName.Substring(1, schemaName.Length - 2); } } } // placeholder json for new textbox element string jsonElement = @"{ ""type"": ""TextBlock"", ""text"": """", ""wrap"": true, }"; if (!String.IsNullOrEmpty(schemaName)) { // get value by schema name from Record if (record.Contains(schemaName)) { string fieldValue = (string)record[schemaName]; // remove html and perform string split fieldValue = ConvertHTMLToText(fieldValue); if (record.LogicalName == "email") { // remove any emails after the first detected email in the chain int stringPosition = fieldValue.IndexOf("From:"); if (stringPosition != -1) { fieldValue = fieldValue.Substring(0, stringPosition); } // attempt to remove signature by mapping from name Microsoft.Xrm.Sdk.EntityCollection collection = (Microsoft.Xrm.Sdk.EntityCollection)record["from"]; string fromValue = collection.ToCommaSeparatedString(); stringPosition = fieldValue.IndexOf(fromValue); if (stringPosition != -1) { fieldValue = fieldValue.Substring(0, stringPosition); } } // dodge - replace multiple line break characters with a unique break string fieldValue = Regex.Replace(fieldValue, "[\r\n\f]", "/crmcs/", System.Text.RegularExpressions.RegexOptions.IgnoreCase); string[] fieldValues = fieldValue.Split(new string[] { "/crmcs/" }, StringSplitOptions.None); for (int i = 0; i < fieldValues.Length; i++) { string value = fieldValues[i]; if (!string.IsNullOrEmpty(value)) { JObject newElement = null; if (i == 0) { // first value to replace current element newElement = o; } else { // next value set as new textbox element newElement = JObject.Parse(jsonElement); } newElement["text"] = value; newArray.Add(newElement); } } } else { // do nothing } } else { newArray.Add(o); } } jobject["body"] = newArray; // return formatted JSON Template as string to keep things consistent return(jobject.ToString()); } catch (Exception ex) { throw new Exception("ProcessDynamicContent :: " + ex.Message); } }