Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Helper not registered first time #327

Closed
joamla96 opened this issue Dec 11, 2019 · 3 comments · Fixed by #359
Closed

Helper not registered first time #327

joamla96 opened this issue Dec 11, 2019 · 3 comments · Fixed by #359

Comments

@joamla96
Copy link

joamla96 commented Dec 11, 2019

I've implemented a fairly simple helper to handle if conditions.
For some reason, when i run the code first time, it ends up throwing an exception that this specific helper is not registered. If I hit the endpoint again, it works perfectly fine and continues to work fine until I restart the application, where it will then throw the exception again the first time.

Don't think it'll help, but cant hurt, the exception it throws:

HandlebarsDotNet.HandlebarsRuntimeException: Template references a helper that is not registered. Could not find helper 'ifCond'
   at HandlebarsDotNet.Compiler.HelperFunctionBinder.LateBindHelperExpression(BindingContext context, String helperName, IEnumerable`1 arguments)
   at lambda_method(Closure , TextWriter , Object )
   at HandlebarsDotNet.Compiler.DeferredSectionVisitor.RenderSection(Object value, BindingContext context, Action`2 body, Action`2 inversion)
   at lambda_method(Closure , TextWriter , Object )
   at HandlebarsDotNet.Handlebars.HandlebarsEnvironment.<>c__DisplayClass7_0.<Compile>b__0(Object context)
   at FileGeneratorService.Service.GeneratePDF(VM_Quote quote) in D:\Users\jola\Source\Repos\Utility Portal\FileGeneratorService\Service.cs:line 224
   at WebAPI.Controllers.QuotesController.GetExport(Int32 id, String type) in D:\Users\jola\Source\Repos\Utility Portal\WebAPI\Controllers\QuotesController.cs:line 293
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
   at WebAPI.MiddlewareDeveloperException.Invoke(HttpContext context) in D:\Users\jola\Source\Repos\Utility Portal\WebAPI\MiddlewareDeveloperException.cs:line 23

and the helper itself:

Handlebars.RegisterHelper("ifCond", (writer, options, context, arguments) =>
{
	if (arguments[0] == null || arguments[1] == null)
	{
		options.Inverse(writer, (object)context);
		return;
	}

	if (arguments[0].ToString() == arguments[1].ToString())
	{
		options.Template(writer, (object)context);
	} else {
		options.Inverse(writer, (object)context);
	}
});
@rexm
Copy link
Member

rexm commented Dec 11, 2019

Can you please also share the template and the code where it is being compiled and invoked?

@joamla96
Copy link
Author

joamla96 commented Jan 7, 2020

A template where its being used looks like this:

		<!-- Spacing Element, because floats are weird -->
		<div style="clear: both; padding-top: 15px;">&nbsp;</div>

        {{Quote.FreeText}}

		{{#productGroups}}
		{{ifCond Category.SystemType 'eq' 'iaas'}}
		{{> ProductGroupsIaas}}
		{{else}}
		{{> ProductGroups}}
		{{/ifCond}}
		{{/productGroups}}

		<br /><br />

		<table>
			<thead>

and the invocation is set up like this:

var bodyTask = File.ReadAllTextAsync(path + "/Body.html");
var headerTask = File.ReadAllTextAsync(path + "/Header.html");
var footerTask = File.ReadAllTextAsync(path + "/Footer.html");

var bodyTemplate = Handlebars.Compile(await bodyTask);
var headerTemplate = Handlebars.Compile(await headerTask);
var footerTemplate = Handlebars.Compile(await footerTask);

Handlebars.RegisterHelper("ifCond", (writer, options, context, arguments) =>
            {
                if (arguments[0] == null || arguments[1] == null || arguments[2] == null)
                {
                    options.Inverse(writer, (object)context);
                    return;
                }

                var passed = false;

                switch (arguments[1])
                {
                    case "eq":
                        if (arguments[0].ToString() == arguments[2].ToString()) passed = true;
                        break;

                    case "grt":
                        if (decimal.Parse(arguments[0].ToString()) > decimal.Parse(arguments[2].ToString())) passed = true;
                        break;
                }


                if (passed)
                {
                    options.Template(writer, (object)context);
                }
                else
                {
                    options.Inverse(writer, (object)context);
                }
            });
var data = new BodyData();
data.Quote = quote;

var dataHF = new DataHeaderFooter();
dataHF.Quote = quote;
dataHF.LogoPath = this.config["LogoPath"];

var bodyHtml = bodyTemplate(data);
var headerHtml = headerTemplate(dataHF);
var footerHtml = footerTemplate(dataHF);

var render = new HtmlToPdf();

var header = new HtmlHeaderFooter() { HtmlFragment = headerHtml, LoadStylesAndCSSFromMainHtmlDocument = true, Height = 30, DrawDividerLine = false };
var footer = new HtmlHeaderFooter() { HtmlFragment = footerHtml, LoadStylesAndCSSFromMainHtmlDocument = true };

render.PrintOptions.MarginTop = header.Height;
render.PrintOptions.MarginBottom = footer.Height;
render.PrintOptions.MarginLeft = 0;
render.PrintOptions.MarginRight = 0;

var result = render
	.RenderHtmlAsPdf(bodyHtml)
	.AddHTMLHeaders(header)
	.AddHTMLFooters(footer);

return result.Stream;

Sorry for the late reply, it got drowned in my feed :D

@artemutin
Copy link

artemutin commented May 7, 2020

I had kind of similar issue, and I was able to fix it by moving helper registration before compilation of any templates

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants