0

Antaris RazorEngine v3.9.3 is used in ASP.NET MVC4 controller to create form element. In result html input elements are rendered outside form element. For example

@using (Html.BeginForm("Test", "Upload"))
{
<input type="file" />
<input type="submit"/>
}

produces

<form action="/Upload/Test" method="post"></form>
<input type="file" />
<input type="submit"/>

while correct result should be

<form action="/Upload/Test" method="post">
<input type="file" />
<input type="submit"/>
</form>

RenderScript returns only input elements. <form action="/Upload/Test" method="post"> is written to output directly. It looks like BeginForm() writes directly to view and Razorengine does not capture its output.

How to fix this ?

View:

        @Model.RenderScript()

Model:

public IHtmlString RenderScript() {
    var config = new TemplateServiceConfiguration();
    config.BaseTemplateType = typeof(HtmlTemplateBase<>);
    config.Namespaces = new HashSet<string>(new string[] {
                    "System",
                    "System.Collections",
                    "System.Collections.Generic",
                    "System.Globalization",
                    "System.Linq",
                    "System.Web",
                    "System.Web.Mvc",
                    "System.Web.Mvc.Html"
                });
    razor = RazorEngineService.Create(config);
    // In real application colModel is retrieved from database
    var colModel=@"
    @using (Html.BeginForm(""Test"", ""Upload""))
    {
    <input type='file' />
    <input type='submit'/>
    }
    ";
    string res = razor.RunCompile(colmodel, colmodel, typeof(object), new object());
    return MvcHtmlString.Create(res);
}

Template base class:

using RazorEngine.Templating;
using RazorEngine.Text;
using System;
using System.IO;
using System.Web;
using System.Web.Mvc;
using System.Web.WebPages;

public class HtmlTemplateBase<T> : TemplateBase<T>, IViewDataContainer
{
    // http://stackoverflow.com/questions/8561164/razorengine-issues-with-html
    HtmlHelper<T> helper = null;
    ViewDataDictionary viewdata = null;

    public HtmlHelper<T> Html
    {
        get
        { 

            // https://github.com/Antaris/RazorEngine/issues/150
             if (helper == null)
            {
                var p = WebPageContext.Current;
                var wvp = p.Page as WebViewPage;
                var context = wvp != null ? wvp.ViewContext : null;

                context.Writer = this.CurrentWriter;

                helper = new HtmlHelper<T>(context, this);
            }

            return helper;
        }
    }


    public ViewDataDictionary ViewData
    {
        get
        {
            if (viewdata == null)
            {
                viewdata = new ViewDataDictionary();
                viewdata.TemplateInfo = new TemplateInfo() { HtmlFieldPrefix = string.Empty };

                if (this.Model != null)
                {
                    viewdata.Model = Model;
                }
            }
            return viewdata;
        }
        set
        {
            viewdata = value;
        }
    }

    public override void WriteTo(TextWriter writer, object value)
    {
        if (writer == null)
            throw new ArgumentNullException("writer");

        if (value == null) return;
        //try to cast to RazorEngine IEncodedString
        var encodedString = value as IEncodedString;
        if (encodedString != null)
        {
            writer.Write(encodedString);
        }
        else
        {
            var htmlString = value as IHtmlString;
            if (htmlString != null) writer.Write(htmlString.ToHtmlString());
            else
            {
                encodedString = TemplateService.EncodedStringFactory.CreateEncodedString(value);
                writer.Write(encodedString);
            }

        }
    }
}

Posted also in https://github.com/Antaris/RazorEngine/issues/443

Andrus
  • 26,339
  • 60
  • 204
  • 378
  • Try giving a name to your input controls inside the form. – Ali Baig Jan 28 '17 at 20:52
  • I added name attribute but problem persists. Please note that the issue is purely about view generation output order, not about input elements. Instead of input elements there can be any other text and problem still occurs. – Andrus Jan 28 '17 at 21:01
  • OK. I did faced this issue last year, I wasn't dead sure how i resolved it. – Ali Baig Jan 28 '17 at 21:40
  • Can you try to find the solution, please. I tried to override other WriteTo method but it looks all they call this WriteTo and BeginForm does not call WriteTo but wrote directly to view – Andrus Jan 28 '17 at 21:52
  • Just a guess, try removing everything from /Bin folder, recompile and run again (although it doesn't make any sense but give it a go)!! – Ali Baig Jan 28 '17 at 22:01
  • I deleted bin and obj folders but problem persists. – Andrus Jan 28 '17 at 22:09
  • That's unfortunate – Ali Baig Jan 28 '17 at 22:23

0 Answers0