8

Im interested in performing JSON transformations and looked into using dotliquid.

In order to avoid having a POCO for the input JSON just to be able to send it as a variable, I would like to send the deserialised JSON. From my understanding, we can't send dynamic to render method, and JObject or JArray does not work as expected. I Tried deserialising to Dictionary< string, object>, but that could not handle nested JSON structures.

liquid

[
{%- for p in data.names -%}
{
"name" : {{ p.name }}
} {%- unless forloop.Last == true -%},{% endunless %}         
{%- endfor -%}
]

C# code

Template template = Template.Parse(File.ReadAllText("Maps/account.liquid"));             
var json = JsonConvert.DeserializeObject<Dictionary<string, object>>(
    @"{ ""names"":[{""name"": ""John""},{""name"":""Doe""}]  }");              

var jsonHash = Hash.FromAnonymousObject(new { Data = json});

Output

[
  {
    "name" : 
  },         
  {
    "name" :  
  }         
]

I know that Microsoft Logic Apps has implemented a similar feature using dotliquid. https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-enterprise-integration-liquid-transform

What different ways are there? Do I need to parse the JObject/JArray to a nested Dictionary, or what alternatives are there?

  • Hi Frederik, I'm on the same issue A.T.M. Tried the logic apps, its way too expensive with the use of that integration account. I tried several libraties, DotLiquid, Liquid.NET and i'm still investigating how to convert a json string to a liquid hash to render my data in another json format. I will keep you updated on my findings... Or do you already have a solution? – Ferry Jongmans Mar 25 '19 at 09:05
  • Hi, I went with the dictionary solution, similar to what's suggested in the accepted answer. Something similar to the second answer to that question. Nevertheless, curious how they have implemented it in Logic Apps, seeing as they use dotliquid – Fredrik Jacobson Mar 26 '19 at 12:44

2 Answers2

7

You can get it to work using the DictionaryConverter from Deserialize JSON recursively to IDictionary<string,object> and Hash.FromDictionary

var json = JsonConvert.DeserializeObject<IDictionary<string, object>>(@"{ ""names"":[{""name"": ""John""},{""name"":""Doe""}]  }", new DictionaryConverter());
var jsonHash = Hash.FromDictionary(json);
var templatetest = "<h1>{{device}}</h1><h2>{{speed}}</h2>{% for client in names %}<h4>{{client.name}}</h4>{% endfor %}";

var template = Template.Parse(templatetest);
var render = template.Render(jsonHash);
JustSomeGuy
  • 3,677
  • 1
  • 23
  • 31
Sixx
  • 130
  • 1
  • 6
0

Another option that might work is to use the ExpandoObject converter:

var jsonObj = JsonConvert.DeserializeObject<ExpandoObject>(json, new Newtonsoft.Json.Converters.ExpandoObjectConverter());

This worked in my use case, but we have a wrapper around the Template that expands usability to accept other types, and it might be that that is handling the dynamic nicely.

DLeh
  • 23,806
  • 16
  • 84
  • 128