diff --git a/source/dotnet/Library/AdaptiveCards.Templating/AdaptiveCardsTemplateSimpleObjectMemory.cs b/source/dotnet/Library/AdaptiveCards.Templating/AdaptiveCardsTemplateSimpleObjectMemory.cs index c29c9ec709..dfaa1e5233 100644 --- a/source/dotnet/Library/AdaptiveCards.Templating/AdaptiveCardsTemplateSimpleObjectMemory.cs +++ b/source/dotnet/Library/AdaptiveCards.Templating/AdaptiveCardsTemplateSimpleObjectMemory.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text; using AdaptiveExpressions.Memory; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace AdaptiveCards.Templating { @@ -37,9 +39,16 @@ public bool TryGetValue(string path, out object value) bool result = simpleObjectMemory.TryGetValue(path, out value); if (value is string) { - string serializedValue = JsonConvert.SerializeObject(value); - // after serialization, the double quotes should be removed - value = serializedValue.Substring(1, serializedValue.Length - 2); + try + { + JToken jsonObject = JToken.Parse(value as string); + } + catch (JsonReaderException) + { + string serializedValue = JsonConvert.SerializeObject(value); + // after serialization, the double quotes should be removed + value = serializedValue.Substring(1, serializedValue.Length - 2); + } } return result; } diff --git a/source/dotnet/Library/AdaptiveCards.Templating/AdaptiveCardsTemplateVisitor.cs b/source/dotnet/Library/AdaptiveCards.Templating/AdaptiveCardsTemplateVisitor.cs index aa22104028..1dc328c22d 100644 --- a/source/dotnet/Library/AdaptiveCards.Templating/AdaptiveCardsTemplateVisitor.cs +++ b/source/dotnet/Library/AdaptiveCards.Templating/AdaptiveCardsTemplateVisitor.cs @@ -172,7 +172,7 @@ private void PushTemplatedDataContext(string jpath) throw new ArgumentNullException("Parent data context or selection path is null"); } - var (value, error) = new ValueExpression("=" + jpath).TryGetValue(parentDataContext.AELMemory); + var (value, error) = new ValueExpression("=" + Regex.Unescape(jpath)).TryGetValue(parentDataContext.AELMemory); if (error == null) { var serializedValue = JsonConvert.SerializeObject(value); diff --git a/source/dotnet/Test/AdaptiveCards.Templating.Test/TestTransform.cs b/source/dotnet/Test/AdaptiveCards.Templating.Test/TestTransform.cs index 76a4cad942..5c31e131ed 100644 --- a/source/dotnet/Test/AdaptiveCards.Templating.Test/TestTransform.cs +++ b/source/dotnet/Test/AdaptiveCards.Templating.Test/TestTransform.cs @@ -13342,6 +13342,131 @@ public void TestWhenExpressionNotInDataWithLog() Assert.AreEqual(expectedWarning, log[0]); } + + [TestMethod] + public void TestJPathOnData() + { + string cardJson = + @"{ + ""$schema"": ""http://adaptivecards.io/schemas/adaptive-card.json"", + ""type"": ""AdaptiveCard"", + ""version"": ""1.3"", + ""body"": [ + { + ""type"": ""TextBlock"", + ""text"": ""${string(jPath(FormMetaData, \""$..FieldOptions[?(@.Name == 'Title')].IsReadOnly\""))}"" + }, + { + ""type"": ""Container"", + ""$when"": ""${not(jPath(FormMetaData, \""$..FieldOptions[?(@.Name == 'Severity')].IsReadOnly\""))}"", + ""items"": [ + { + ""type"": ""Input.ChoiceSet"", + ""id"": ""Severity"", + ""style"": ""expanded"", + ""choices"": [ + { + ""$data"": ""${jPath(FormMetaData, \""$..FieldOptions[?(@.Name == 'Severity')].Options\"")}"", + ""title"": ""${Title}"", + ""value"": ""${Value}"" + } + ], + ""label"": ""Severity of the Incident"", + ""isRequired"": true, + ""errorMessage"": ""Severity of the Incident"" + } + ] + } + ] + }"; + + string expectedJson = + @"{ + ""$schema"": ""http://adaptivecards.io/schemas/adaptive-card.json"", + ""type"": ""AdaptiveCard"", + ""version"": ""1.3"", + ""body"": [ + { + ""type"": ""TextBlock"", + ""text"": ""false"" + }, + { + ""type"": ""Container"", + ""items"": [ + { + ""type"": ""Input.ChoiceSet"", + ""id"": ""Severity"", + ""style"": ""expanded"", + ""choices"": [ + { + ""title"": ""1"", + ""value"": ""1"" + }, + { + ""title"": ""2"", + ""value"": ""2"" + }, + { + ""title"": ""3"", + ""value"": ""3"" + }, + { + ""title"": ""4"", + ""value"": ""4"" + } + ], + ""label"": ""Severity of the Incident"", + ""isRequired"": true, + ""errorMessage"": ""Severity of the Incident"" + } + ] + } + ] + }"; + + var context = new EvaluationContext() + { + Root = + @"{ + ""Title"": ""Issue with "", + ""FormMetaData"": { + ""FieldOptions"": [ + { + ""Name"": ""Title"", + ""IsReadOnly"": false, + ""Options"": [] + }, + { + ""Name"": ""Severity"", + ""IsReadOnly"": false, + ""Options"": [ + { + ""Title"": ""1"", + ""Value"": ""1"" + }, + { + ""Title"": ""2"", + ""Value"": ""2"" + }, + { + ""Title"": ""3"", + ""Value"": ""3"" + }, + { + ""Title"": ""4"", + ""Value"": ""4"" + } + ] + } + ] + } + }" + }; + + var template = new AdaptiveCardTemplate(cardJson); + string st = template.Expand(context); + AssertJsonEqual(expectedJson, st); + } } [TestClass] public sealed class TestRootKeyword