The very first sample does not work

Mar 6, 2011 at 7:26 AM

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RazorEngine;

namespace RazorDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            string template = "Hello @Model.Name! Welcome to Razor!";
            string result = Razor.Parse(template, new { Name = "World" });
            Console.WriteLine(result);
        }
    }
}

when you run this code, it throws exception.

Unhandled Exception: RazorEngine.Templating.TemplateCompilationException: Unable
 to compile template. Check the Errors list for details.
   at RazorEngine.Compilation.DirectCompilerServiceBase.CompileType(TypeContext
context)
   at RazorEngine.Templating.TemplateService.CreateTemplate(String template, Typ
e modelType)
   at RazorEngine.Templating.TemplateService.GetTemplate(String template, Type m
odelType, String name)
   at RazorEngine.Templating.TemplateService.Parse[T](String template, T model,
String name)
   at RazorEngine.Razor.Parse[T](String template, T model, String name)
   at RazorDemo.Program.Main(String[] args) in c:\@codetemp\NvelocityDemo\RazorD
emo\Program.cs:line 14
Press any key to continue . . .

Coordinator
Mar 7, 2011 at 8:54 AM

Hi,

Can you run the project again, and check what compilation errors you have? They will be in the .Errors property of the TemplateCompilationException thrown.

Mar 7, 2011 at 9:01 AM
Edited Mar 7, 2011 at 9:02 AM

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RazorEngine;
using RazorEngine.Templating;

namespace RazorDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                string template = "Hello @Model.Name! Welcome to Razor!";
                string result = Razor.Parse(template, new { Name = "World" });
                Console.WriteLine(result);
            }
            catch (TemplateCompilationException ex)
            {

                ex.Errors.ToList().ForEach(p => Console.WriteLine(p.ErrorText));
            }
            
        }
    }
}

 

 

Here it is. 

Predefined type 'Microsoft.CSharp.RuntimeBinder.Binder' is not defined or importedOne or more types required to compile a dynamic expression cannot be found. Areyou missing references to Microsoft.CSharp.dll and System.Core.dll?One or more types required to compile a dynamic expression cannot be found. Areyou missing references to Microsoft.CSharp.dll and System.Core.dll?Press any key to continue . . .

 

but I had Microsoft.Csharp and System.Core in my project reference. 

 

Mar 7, 2011 at 9:08 AM

I just test it again, found some interesting things.  If I Press Ctrl+F5, it through exception. but when I run step by step from vs2010, works fine. I then go to bin folder under Command Mode and execute the exe file. it also throw exception.

Coordinator
Mar 7, 2011 at 9:54 AM

What version of .NET are you trying to use this with?

Mar 7, 2011 at 10:24 AM

.NET 4

Coordinator
Mar 7, 2011 at 12:35 PM

Hi,

Can you send me a copy of your sample project? Please send it to matt [at] fidelitydesign [dot] net

Mar 13, 2011 at 8:58 AM

Hi Matt

Did you get my sample solution and manage to fix the problem?

Coordinator
Mar 14, 2011 at 9:26 AM

Hi,

Sorry for the late reply, had a weekend off enjoying my birthday :-) Checked my email this morning and the attached archive won't open. Can you resend?

Mar 14, 2011 at 11:05 AM

Hi,

Add Microsoft.CSharp as reference. This should fix your problem.

Mar 14, 2011 at 11:07 AM

no I had that under reference folder

 

see my previous comment

 

I just test it again, found some interesting things.  If I Press Ctrl+F5, it through exception. but when I run step by step from vs2010, works fine. I then go to bin folder under Command Mode and execute the exe file. it also throw exception.

Mar 14, 2011 at 11:19 AM

you've tried recreating again the project, targetting 4.0 from the start?

Mar 23, 2011 at 3:32 PM

I am experiencing the similar problem. I can call the following class from a console app and it works OK. However, I get the errors described above when I create a test project and run from there.

namespace ClassLibrary1 {
    public class Class1 {

        public Class1() { }

        public string RunTest() {
                                  
            string template = "Hello @Model.Name! Welcome to Razor!";
            string result = "";
            result = Razor.Parse(template, new {
                Name = "World"
            });

            return result;
        }

    }
}

I can package up the test project and send to you if needed.

 


 

Mar 23, 2011 at 3:52 PM

One update... I found the problem is isolated to Dynamic classes. I ran the following class from the Test project without any errors:

 

        public string RunTestGenerics() {
                                  
            string template = "Hello @Model.Name! Welcome to Razor!";
            MyModel myModel = new MyModel();
            myModel.Name = "World";
            string result = "";
            result = Razor.Parse<MyModel>(template, myModel);
               
            return result;
        }
 

 

Coordinator
Mar 23, 2011 at 7:34 PM

Hi, it's definately to do with dynamics, as its the RuntimeBinder used for C# dynamic support that is causing the issues. Using a typed model won't suffer, as all the types are correctly referenced. Haven't had a chance to fully look into this.

Mar 24, 2011 at 2:48 PM
AntarisZX wrote:

Hi, it's definately to do with dynamics, as its the RuntimeBinder used for C# dynamic support that is causing the issues. Using a typed model won't suffer, as all the types are correctly referenced. Haven't had a chance to fully look into this.

Just figured out yesterday that if I use an anonymouse type as a model, extension methods don't work (although I added a necessary namespace reference). But when I use a typed model it works like a charm.

Apr 14, 2011 at 1:25 PM

I'm getting exactly the same error as the original poster with the Hello World example.

It seemingly is related to dynamic in some way, as the following test shows in my environment.

        [Test]
        public void ShoudSpikeTheSillyError()
        {
            string template = "Hello @Model.Name!";
            Assert.Throws<RazorEngine.Templating.TemplateCompilationException>(() => Razor.Parse(template, new { Name = "World" }));

            InitializeRazorParser();

            Assert.DoesNotThrow(() => Razor.Parse(template, new { Name = "World" }));
        }

And the magic in InitializeRazorParser() ?????

        void InitializeRazorParser()
        {
            // HACK: this is required to get the Razor Parser to work, no idea why, something to with dynamic objects i guess, tracked this down as the test worked sometimes, turned out
            // it was when the ViewBag was touched from the controller tests, if that happened before the Razor.Parse in ShoudSpikeTheSillyError() then it ran fine.
            dynamic x2 = new ExpandoObject();
            x2.Dummy = "";
        }
Not sure if that helps understand the issue any better, its a strange one though!.


Coordinator
Apr 15, 2011 at 8:59 PM

This sounds like another problem with references not being loaded properly by .net. I'm working on solidifying a solution to make sure that their loaded but I haven't tested it with Razor yet.

May 4, 2011 at 9:07 PM

I'm having this same problem.

When I run with debug enabled it works, but when I run without debug it fails with 

Unhandled Exception: RazorEngine.Templating.TemplateCompilationException: Unable to compile template. Check the Errors list for details.

Jun 15, 2011 at 4:02 AM

Its not as easy as adding web package reference with NuGet and run the sample code and test how it works.

Simple HelloWorld is throwing several issues.

First I have installed RazorEngine using NuGet command. Then it complained about syntax errors in the template. It could not understand what "@Html" is.

Then after looking at the documentation I have added the following section in the web.config.

<configSections>
		<section name="razorEngine" type="RazorEngine.Configuration.RazorEngineConfigurationSection, RazorEngine" requirePermission="false" />
	</configSections>
	<razorEngine activator="RazorEngineSamples.Activators.MySampleActivator, RazorEngineSamples"
                 factory="RazorEngine.Web.WebCompilerServiceFactory, RazorEngine.Web">
		<namespaces>
			<add namespace="System.Linq" />
		</namespaces>		
	</razorEngine

After adding this section now its throwing exceptions because it could not load the assemblies.
First it said RazorEngine.Web is not found. But there was no dependency shown in the NuGet package.
Then I installed RazorEngine.Web too.
Now it could not find RazorEngineSample.Activators.....
Even I could not find any such package in the RazorEngine project!!!

Jun 21, 2011 at 11:48 AM

Hi,

I am not sure this can be done. There is a bug logged at microsoft connect which indicates that this might not be possible.
http://connect.microsoft.com/VisualStudio/feedback/details/491554/clr-dynamic-runtime-binder-does-not-support-typedescriptors
If you read nicoscent's comment you will see a simple example where this doesn't work. I managed to hack RazorEngine to run this sample.

			Razor.SetTemplateBase(typeof(RazorEngine.Templating.TemplateBase<dynamic>));
			string template = "Hello @Model.Name! Welcome to Razor!";
			dynamic x2 = new System.Dynamic.ExpandoObject();
			string result = Razor.Parse(template, new { Name = "World" });
			return result;

Unfortunately after hacking away, I still eventually get this error:
'object' does not contain a definition for 'Name' and no extension method 'Name' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)}I have coded up my own Razor engine host and tried to overcome this issue and cannot find a workaround. I am not certain if the bug above is exactly the same issue, but it certainly seems to be.

In the interim I have written a method to change the anonymous type into an ExpandoObject using reflection, this is not ideal, but it does work.

		public static dynamic ToDynamic(object instance)
		{
			var x = new System.Dynamic.ExpandoObject();
			var values =
				from property in instance.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
				select new
				{
					Name = property.Name,
					Value = property.GetValue(instance, null)
				};
			foreach (var property in values)
				(x as IDictionary<stringobject>).Add(property.Name, property.Value);
			return x;
		}

I would really like to know if anyone has managed to get any other workarounds to work.

Jun 21, 2011 at 1:08 PM

Hi Everyone,

I have more information. This is actually (also) because anonymous classes have internal properties, and the model binder can't see them.
I have tried adding internalsvisibleto in order to overcome the issue, but I have not yet succeeded.

Here is more information: http://stackoverflow.com/questions/5120317/dynamic-anonymous-type-in-razor-causes-runtimebinderexception

I am not sure how to proceed to get that sample to work. It looks like it might be by design.

Cheers
Craig

Jul 20, 2011 at 10:33 AM

@jkll's solution worked for me - ensure this gets run before anything else:

 

bool loaded = typeof(Microsoft.CSharp.RuntimeBinder.Binder).Assembly != null;