Search code examples
c#.netrazorrazorengine

Razor ViewEngine Temporary compilation .cs files


When calling the Parse method in the Razor ViewEngine, compilation errors are thrown as TemplateComplilationException which contains a list of errors. Those errors refer to temporary filenames, but the files are deleted before you can access them.

static void Main(string[] args)  
{
    var service = TemplateServiceFactory.CreateTemplateService(Language.CSharp, true);
    string result = "";
    try
    {
       result = service.Parse("Hello @DateTime.NowXX ");
    }
    catch (TemplateCompilationException ex)
    {
      foreach (var error in ex.Errors)
         if (!string.IsNullOrEmpty(error.FileName))
             Console.WriteLine( File.ReadAllText( error.FileName ));
    }  //                                         ^^^^ File does not exist!

    Console.WriteLine( result );       
    Console.ReadKey();
    }

(a little background) I'm using the Razor engine "stand-alone" without MVC. When I call the Parse I want to get as much detailed information as possible to display to the user.


Solution

  • RazorEngine's TemplateCompilationException is a class that wraps a CompilerErrorCollection that contain CompilerError objects, so the most details you could possibly get from the TemplateCompilationException CompilerError objects are their respective properties, which appears to be enough to debug with. Consider and try this example

    try
    {
        Razor.Parse("My erroneous @DateTime.Now.foo()");
    }
    catch(TemplateCompilationException ex)
    {
        foreach(var error in ex.Errors)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("Compile Error Num: \t" + error.ErrorNumber);
            sb.AppendLine("Error Text:\n\t" + error.ErrorText);
            Console.WriteLine(sb.ToString());
        }
        Console.WriteLine("Erroneous Template:\n\t" + ex.Template);
    }
    

    When I run my example this is what I get, which tells you the error(s) that was encountered and you can dump the template data to reference for your users.

    Compile Error Num:   CS1061
    Error Text:
      'System.DateTime' does not contain a definition for 'foo' and no 
      extension method     'foo' accepting a first argument of type 
      'System.DateTime' could be found (are you missing a using directive 
      or an assembly reference?)
    
    Erroneous Template:
        My erroneous @DateTime.Now.foo()