Skip to content
Julian Verdurmen edited this page Jul 22, 2021 · 11 revisions

By default, RazorEngine will not encode values to be HTML safe, you need to escape values by yourself

IRazorEngine razorEngine = new RazorEngine();
IRazorEngineCompiledTemplate template = razorEngine.Compile("Hello @Model.Name");

string result = template.Run(new
{
    Name = "<b>Test</b>"
});

Console.WriteLine(result);

will output

Hello <b>Test</b>

Extension

IRazorEngine razorEngine = new RazorEngine();
IRazorEngineCompiledTemplate template = razorEngine.Compile("Hello @Model.Name");

string result = template.RunHtmlSafe(new
{
    Name = "<script>Hello</script>"
});

Console.WriteLine(result);

Output:

<h1>&lt;script&gt;Hello&lt;/script&gt;</h1>

Code

public static class RazorEngineExtensions
{
    public static string RunHtmlSafe(this RazorEngineCompiledTemplate template, object model = null)
    {
        return template.Run(new HtmlSafeAnonymousTypeWrapper (model));
    }
}
public class HtmlSafeAnonymousTypeWrapper : DynamicObject
{
    private readonly object model;

    public HtmlSafeAnonymousTypeWrapper(object model)
    {
        this.model = model;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        PropertyInfo propertyInfo = this.model.GetType().GetProperty(binder.Name);

        if (propertyInfo == null)
        {
            result = null;
            return false;
        }

        result = propertyInfo.GetValue(this.model, null);

        if (result == null)
        {
            return true;
        }

        var type = result.GetType();

        if (result.IsAnonymous())
        {
            result = new HtmlSafeAnonymousTypeWrapper(result);
        }

        if (type.IsArray)
        {
            result = ((IEnumerable<object>)result).Select(e => new HtmlSafeAnonymousTypeWrapper(e)).ToList();
        }

        if (result is string)
        {
            result = WebUtility.HtmlEncode(result.ToString());
        }

        return true;
    }
}