سؤال

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.

هل كانت مفيدة؟

المحلول

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()

نصائح أخرى

The current v2.1 release doesn't provide the ability to spit out the source code. There is a debugging feature in the new v3 codebase that allows the source code to be pushed out. It doesn't do this by default, because I'm trying to make the code as performant as possible (and generating the code twice (once as CodeDom, once as a string) isn't ideal). You'll need to enable the Debug flag on your configuration:

var config = new TemplateServiceConfiguration { Debug = true };
var service = new TemplateService(config);

This will enable the source code to be read when an exception is thrown.

Point of interest, through testing the Roslyn compiler infrastructure with the v3 codebase, it accepts a string source instead of CodeDom, so I'll likely make a future change to use that instead of CodeDom directly - this in turn means we have direct access to the source code without having to worry about enabling any Debug flag which will likely be deprecated.

v3 (currently v3.0.7beta) is available on Nuget (Install-Package RazorEngine). I was aiming to RTW last weekend but never got round to it.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top