question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Followed @Include and @Layout wiki But Getting Exception

See original GitHub issue

Target Framework is net48. Here’s the MWE :

using System;
using System.Collections.Generic;
using System.Linq;
using RazorEngineCore;

namespace mwe
{
    public static class RazorEngineCoreExtensions
    {
        public static RazorCompiledTemplate Compile(this IRazorEngine razorEngine, string template, IDictionary<string, string> parts)
        {
            return new RazorCompiledTemplate(
                    razorEngine.Compile<RazorTemplateBase>(template),
                    parts.ToDictionary(
                            k => k.Key,
                            v => razorEngine.Compile<RazorTemplateBase>(v.Value)));
        }
    }
    
    public class RazorTemplateBase: RazorEngineTemplateBase
    {
        public Func<string, object, string> IncludeCallback { get; set; }

        public Func<string> RenderBodyCallback { get; set; }
        public string Layout { get; set; }

        public string Include(string key, object model = null)
        {
            return this.IncludeCallback(key, model);
        }

        public string RenderBody()
        {
            return this.RenderBodyCallback();
        }
    }

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

        public string Age{get; set;}

        public void Initialize()
        {
            Name = "name";
            Age = "age";
        }
    }

    public class RazorCompiledTemplate
    {
        private readonly IRazorEngineCompiledTemplate<RazorTemplateBase> compiledTemplate;
        private readonly Dictionary<string, IRazorEngineCompiledTemplate<RazorTemplateBase>> compiledParts;

        public RazorCompiledTemplate(IRazorEngineCompiledTemplate<RazorTemplateBase> compiledTemplate, Dictionary<string, IRazorEngineCompiledTemplate<RazorTemplateBase>> compiledParts)
        {
            this.compiledTemplate = compiledTemplate;
            this.compiledParts = compiledParts;
        }

        public string Run(object model)
        {
            return this.Run(this.compiledTemplate, model);
        }

        public string Run(IRazorEngineCompiledTemplate<RazorTemplateBase> template, object model)
        {
            RazorTemplateBase templateReference = null;

            string result = template.Run(instance =>
            {
                // if I comment out the following if clause, it works.
                if (!(model is AnonymousTypeWrapper))
                {
                    model = new AnonymousTypeWrapper(model);
                }

                instance.Model = model;
                instance.IncludeCallback = (key, includeModel) => this.Run(this.compiledParts[key], includeModel);

                templateReference = instance;
            });

            if (templateReference.Layout == null)
            {
                return result;
            }

            return this.compiledParts[templateReference.Layout].Run(instance =>
            {
                if (!(model is AnonymousTypeWrapper))
                {
                    model = new AnonymousTypeWrapper(model);
                }

                instance.Model = model;
                instance.IncludeCallback = (key, includeModel) => this.Run(this.compiledParts[key], includeModel);
                instance.RenderBodyCallback = () => result;
            });
        }
    }

    public class Program
    {
        static void Main(string[] args)
        {
            var model = new TestModel();
            var testpayload = @"

@inherits RazorEngineCore.RazorEngineTemplateBase<TestModel>
@{
    Model.Initialize();
}
    <b>@Model.Name</b>
";
            var engine = new RazorEngine();
            var compiled = engine.Compile(testpayload, new Dictionary<string, string>());

            var result = compiled.Run(model);
            Console.WriteLine(result);
            Console.ReadKey();
        }
    }
}

Here’s the exception I get when I run this mwe:

D:\mwe> dotnet run .\Program.cs
Unhandled Exception: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'RazorEngineCore.AnonymousTypeWrapper' does not contain a definition for 'Initialize'
   at CallSite.Target(Closure , CallSite , Object )
   at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid1[T0](CallSite site, T0 arg0)
   at TemplateNamespace.Template.<ExecuteAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at RazorEngineCore.RazorEngineCompiledTemplate`1.<RunAsync>d__12.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at RazorEngineCore.RazorEngineCompiledTemplate`1.Run(Action`1 initializer)
   at mwe.RazorCompiledTemplate.Run(IRazorEngineCompiledTemplate`1 template, Object model) in D:\mwe\Program.cs:line 71
   at mwe.RazorCompiledTemplate.Run(Object model) in D:\mwe\Program.cs:line 64
   at mwe.Program.Main(String[] args) in D:\mwe\Program.cs:line 119

Any idea where I did it wrong? If I just fall back to the basic usage, it also works:

 var compiled = engine.Compile(testpayload);
 var result = compile.Run(model);
 Console.WriteLine(result);
 Console.ReadKey();

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
adoconnectioncommented, Mar 4, 2021

I’ll implement same idea as you do in PR “in completely different way” not to make any concerns about it 😃

closing issue for now

2reactions
adoconnectioncommented, Feb 21, 2021

Yes, AnonymousTypeWrapper does not implement functions calls (until you did it). I think this code should be added in next version.

However this code is looks odd to me:

@{
   Model.Initialize();
}

The idea was to initialize model on compiled.Run moment, not in the template. When template is being executed it is too late on initialize model.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Exception while creating Wiki page using CSOM
I am getting exception: Cannot invoke method or retrieve property from null object. Object returned by the following call stack is null. c# ......
Read more >
Wikipedia:Fair use images in templates: exceptions
The clear intent of banning fair use images from templates is that each and every use of such images must be legally justifiable....
Read more >
Wikipedia:Exceptions should leave the rule intact
Rather, any exceptions to the rule should leave the rule intact. Another way of putting this is use common sense when it comes...
Read more >
Wikipedia:Manual of Style/Layout
This guide presents the typical layout of Wikipedia articles, including the sections an article usually has, ordering of sections, and formatting styles for ......
Read more >
Help:Wikitext
Templates are segments of wiki markup that are meant to be copied automatically ("transcluded") into a page. They are specified by putting the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found