Because dotLiquid does not support member-level attribute decoration, I've created a custom attribute for my project and I'm registering the types and properties at run-time using the Template.RegisterSafeType()
method of drop registration.
In other words, instead of the LiquidType
class attribute like this...
[LiquidType("MyExposedValue")]
public class MyClass
{
public string MyExposedValue { get; set; }
public string MyHiddenValue { get; set; }
}
... I use my own custom dual-level attribute like this:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = false)]
public class LiquidSafeAttribute : Attribute
{
}
[LiquidSafe]
public class MyClass
{
[LiquidSafe]
public string MyExposedValue { get; set; }
// No [LiquidSafe] attribute on this property, therefore not exposed
public string MyHiddenValue { get; set; }
}
Then on app startup, I reflect over the types in the assembly and pass the decorated properties into Template.RegisterSafeType
:
foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
{
if (type.GetCustomAttribute<LiquidSafeAttribute>() != null)
{
Template.RegisterSafeType(type, type.GetProperties()
.Where(p => Attribute.IsDefined(p, typeof(LiquidSafeAttribute)))
.Select(p => p.Name).ToArray()
);
}
}
This works fine for everything... except generics:
[LiquidSafe]
public class MyClass<T>
{
[LiquidSafe]
public T MyExposedValue { get; set; }
public string MyHiddenValue { get; set; }
}
For example, if I try to render a MyClass<string>
, I get an error:
Liquid syntax error: Object 'DotLiquidTest.MyClass`1[System.String]' is invalid because it is neither a built-in type nor implements ILiquidizable
However, I've found that if I create a new class that inherits from MyClass<string>
, it works fine:
[LiquidSafe]
public class MyStringClass : MyClass<string>
{
}
Here's the .NET fiddle demonstrating the working implementation with the non-generic class: http://ift.tt/2iVaHDY.
And here is the .NET fiddle showing how the generic version blows up on render: http://ift.tt/2iVaHDY
The generic class worked back when I was using the LiquidType
attribute. Any ideas on why it's not working with the Template.RegisterSafeType()
way of registering safe types?
Aucun commentaire:
Enregistrer un commentaire