HTML is being rendered as literal string using Raz

2019-01-28 03:05发布

问题:

I'm trying to generate a HTML document with RazorEngine (http://razorengine.codeplex.com/). Everything is mostly working, but the problem I have now is some of the HTML is being rendered correctly, and HTML that I have nested in that is being rendered as literal HTML, so rather than the browser displaying the tables & divs as expected, it's displaying e.g.

 "<table></table><div></div>"

I kick off this process by calling the following:

string completeHTML = RazorEngine.Razor.Parse("InstallationTemplate.cshtml", new { Data = viewModels });

The completeHTML is then written to a file.

"InstallationTemplate.cshtml" is defined as:

@{
    var installationReport = new InstallationReport(Model.Data);
}

<!DOCTYPE html>
<html>
    <head></head>
    <body>        
        <div>
            <!-- I would expect this to write the rendered HTML
                 in place of "@installationReport.DigiChannels()" -->
            @installationReport.DigiChannels()    
        </div>
    </body>
</html>

Where InstallationReport and DigiChannels are defined as follows:

public static class InstallationReportExtensions
{
    public static string DigiChannels(this InstallationReport installationReport)
    {
        return installationReport.GetDigiChannelsHtml();
    }
}

public class InstallationReport
{
    public string GetDigiChannelsHtml()
    {
        // the following renders the template correctly
        string renderedHtml = RazorReport.GetHtml("DigiChannels.cshtml", GetDigiChannelData());
        return renderedHtml;
    }
}

public static string GetHtml(string templateName, object data)
{
    var templateString = GetTemplateString(templateName);

    return RazorEngine.Razor.Parse(templateString, data);
}

After GetDigiChannelsHtml() runs and returns renderedHtml, the line of execution returns to TemplateBase.cs into the method ITemplate.Run(ExecuteContext context), which is defined as:

    string ITemplate.Run(ExecuteContext context)
    {
        _context = context;

        var builder = new StringBuilder();
        using (var writer = new StringWriter(builder)) 
        {
            _context.CurrentWriter = writer;

            Execute(); // this is where my stuff gets called

            _context.CurrentWriter = null;
        }

        if (Layout != null)
        {
            // Get the layout template.
            var layout = ResolveLayout(Layout);

            // Push the current body instance onto the stack for later execution.
            var body = new TemplateWriter(tw => tw.Write(builder.ToString()));
            context.PushBody(body);

            return layout.Run(context);
        }

        return builder.ToString();
    }

When I inspect builder.ToString(), I can see it contains proper HTML for the InstallationTemplate.cshtml stuff, and escaped HTML for the DigiChannels.cshtml stuff. For example:

How can I get @installationReport.DigiChannels() to include the correct HTML instead of the escaped HTML that it's currently doing?

回答1:

Have you tried:

@Raw(installationReport.DigiChannels())

Edit : I could use it in following way (MVC3)

@Html.Raw(installationReport.DigiChannels())


回答2:

The alternative to @Raw is to change your API to return HtmlStrings in appropriate places

Represents an HTML-encoded string that should not be encoded again.

The default razor behaviour is to encode strings.



标签: c# razor