sebastienros/fluid

Render using System.Text.Json.JsonElement as a model

Closed this issue · 2 comments

To help future users.

How to generate a template using an instance of System.Text.Json.JsonElement.

Notes:

  • This example does case-insensitive comparison on the property name.
  • Using dotnet 6 and Fluid 2.2.16
using System.Text.Json;
using Fluid;

....
var parser = new FluidParser();
var options = new TemplateOptions();

// How Fluid will access the properties on the JsonElement.
options.MemberAccessStrategy.Register<JsonElement, object>((obj, name) =>
{
    var property = obj.EnumerateObject()
        .FirstOrDefault(p => string.Equals(p.Name, name, StringComparison.OrdinalIgnoreCase));
    return property.Value;
});

// deserialize JSON
var data = JsonSerializer.Deserialize<JsonElement>(jsonString);
    
var parsedTemplate = parser.Parse(template);

var generatedContent = parsedTemplate.Render(new TemplateContext(data, Options));

Of course if you have any corrections or suggestions to the above please comment.

var options = new TemplateOptions();
options.MemberAccessStrategy.Register();

这样行不行

rudiv commented

To handle additional types within the JSON value, this can be used:

var property = obj.EnumerateObject()
    .FirstOrDefault(p => string.Equals(p.Name, name, StringComparison.OrdinalIgnoreCase));

switch (property.Value.ValueKind)
{
    case JsonValueKind.String:
        return property.Value.TryGetDateTime(out var dt) ? dt : property.Value.ToString();
    case JsonValueKind.False:
    case JsonValueKind.True:
        return property.Value.GetBoolean();
    case JsonValueKind.Number:
        return property.Value.TryGetInt32(out var i) ? i : property.Value.GetDouble();
}

return property.Value;