Skip to content

@Html implementation example

Alexander edited this page Jan 11, 2021 · 2 revisions

@Html is a part of Mvc therefore it is absent in RazorEngine. @Html does a lot of things internally like accessing ViewState, Routes etc so you cant use it simply referencing AspNet.Mvc namespace.

In order to use @Html in template it must contain initialized public HtmlHelper<T> Html { get; set; } property

public class TestModel
{
    public string StudentId { get; set; }
}

public class MvcTemplate<T> : RazorEngineTemplateBase<T>
{
    public MyHtmlHelper<T> Html { get; set; }
}

public class MyHtmlHelper<T>
{
    private readonly MvcTemplate<T> templateInstance;

    public MyHtmlHelper(MvcTemplate<T> templateInstance)
    {
        this.templateInstance = templateInstance;
    }

    public string Hidden(Expression<Func<T, object>> selector)
    {
        object propertyValue = selector.Compile()(this.templateInstance.Model);

        MemberExpression body = (MemberExpression)selector.Body;

        string name = HttpUtility.HtmlAttributeEncode(body.Member.Name);
        string value = HttpUtility.HtmlAttributeEncode(propertyValue?.ToString() ?? "");

        return $"<input type=\"hidden\" name=\"{name}\" value=\"{value}\" \\>";
    }
}

class Program
{
    static void Main(string[] args)
    {
        string content = @"
              <p>hidden: @Html.Hidden(m => m.StudentId)</p>                  
          ";

        RazorEngine razorEngine = new RazorEngine();

        var compiledTemplate = razorEngine.Compile<MvcTemplate<TestModel>>(content);

        string result = compiledTemplate.Run(template =>
        {
            template.Model = new TestModel()
            {
                    StudentId = "<script>alert(\"1\");</script>"
            };

            template.Html = new MyHtmlHelper<TestModel>(template);
        });

        Console.WriteLine(result);
        Console.ReadKey();
    }
}