Визуализация шаблона scriban из json данных - PullRequest
0 голосов
/ 25 февраля 2020

Я хотел бы отобразить шаблон Scriban с ExpandoObject или любым другим типом данных, который может быть сгенерирован из строки JSON:

var json = "....";                
var dyn = JsonConvert.DeserializeObject<ExpandoObject>(json);                    
var template = Scriban.Template.Parse("Hello {{ data.foo }}!");                    
var result = template.Render(dyn);

Scriban не работает с ExpandoObject s , так как они анализируются как список { key = '', value = '' } объектов. Объявление типа для данных не является вариантом в моем случае использования, так как схема JSON априори неизвестна.

  • Приведение ExpandoObject к dynamici c показывает то же поведение, что и используя ExpandoObject напрямую.

  • Я пытался десериализовать JSON в dynamic, что приводит к исключению:

System.Reflection. TargetParameterCountException: «Несоответствие количества параметров».

Можно ли как-то преобразовать данные или настроить Scriban для рендеринга данных Dynami c?

Ответы [ 2 ]

1 голос
/ 30 марта 2020

В случаях, когда у вас есть простой объект, вы можете попробовать что-то вроде этого.

var json = "{\"Phone\":\"555000000\",\"Name\":\"Maia\"}";
var scriptObject = new Scriban.Runtime.ScriptObject();
var data = JsonConvert.DeserializeObject<ExpandoObject>(json);
foreach (var prop in data)
{
   scriptObject.Add(prop.Key, prop.Value);
}
var templateCtx = new Scriban.TemplateContext();
templateCtx.PushGlobal(scriptObject);
var template = Scriban.Template.Parse("Hello {{Name}}");
var result = template.Render(templateCtx); // result will be "Hello Maia"
0 голосов
/ 18 апреля 2020

Основываясь на предыдущем ответе, это решение для сложных объектов:

public static class ScribanRenderer
{
    public static string RenderJson(string json, string content)
    {

        var expando = JsonConvert.DeserializeObject<ExpandoObject>(json);
        var sObject = BuildScriptObject(expando);
        var templateCtx = new Scriban.TemplateContext();
        templateCtx.PushGlobal(sObject);
        var template = Scriban.Template.Parse(content);
        var result = template.Render(templateCtx);

        return result;
    }

    private static ScriptObject BuildScriptObject(ExpandoObject expando)
    {
        var dict = (IDictionary<string, object>) expando;
        var scriptObject = new ScriptObject();

        foreach (var kv in dict)
        {
            var renamedKey = StandardMemberRenamer.Rename(kv.Key);

            if (kv.Value is ExpandoObject expandoValue)
            {
                scriptObject.Add(renamedKey, BuildScriptObject(expandoValue));
            }
            else
            {
                scriptObject.Add(renamedKey, kv.Value);
            }
        }

        return scriptObject;
    }
}

Он использует тот факт, что сложные свойства ExpandoObject всегда ExpandoObjects, когда он десериализуется из JSON , Он рекурсивно добавляет ScriptObjects для сложных типов элементов и сам объект для всех других свойств в `` ScriptObject`.

Обратите внимание, что мое решение использует переименование элемента Scriban по умолчанию, где FirstName становится first_name и т. д.

...