Skip to content

RazorEngineCore.ObjectExtenders.IsAnonymous(this object obj) not recognizing dynamic or anonymous types #135

@seppo498573908457

Description

@seppo498573908457

In my testing I noticed that when I enter dynamic typed or a proper anonymous typed model into the RazorEngineCore through some generic methods, I got error:

Unable to compile template: (35,77): error CS1003: Syntax error, ',' expected
(35,80): error CS1003: Syntax error, ',' expected
(35,125): error CS1003: Syntax error, ',' expected
(35,80): error CS0246: The type or namespace name 'f__AnonymousType1<,>' could not be found (are you missing a using directive or an assembly reference?)

Error is thrown when calling Compile<>:

RazorEngineCore.IRazorEngine engine = new RazorEngineCore.RazorEngine();

void optBuilder(IRazorEngineCompilationOptionsBuilder builder)
{
    Assembly[] all = AppDomain.CurrentDomain.GetAssemblies();
    foreach (Assembly asm in all)
    {
        if (asm.IsDynamic) { continue; }
        builder.AddAssemblyReference(asm);
    }
}
var template4 = engine.Compile<MyTemplate<T>>(templateSource, optBuilder); // This row throws!
string result = template4.Run(tmpl =>
{
    tmpl.Model = model;
});

Line 35 in generated code:

public class Template : RazorTestLib48.RazorEngineCoreHelpers.MyTemplate<<>f__AnonymousType1<System.String,System.Int32>>

Creation of model:

  dynamic model = new
  {
      Name = "Testi",
      Age = 3
  };
// or:
    var model = new
    {
        Name = "Testi",
        Age = 3
    };

When debugging that model has a type named "<>f__AnonymousType1`2", it returns true for all the other checks in IsAnonymous:

  • Attribute.IsDefined(type, typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), inherit: false)
  • type.IsGenericType
  • type.Name.Contains("AnonymousType")
  • (type.Name.StartsWith("<>") || type.Name.StartsWith("VB$"))

Except for the last type.Attributes.HasFlag(TypeAttributes.NotPublic) although it has properties type.IsPublic = false and type.IsNotPublic = true.

Using a strongly typed class does not throw errors. I'm running a dotnet6 console app that references a dotnet48 library for proof-of-concept purposes. Am I doing something wrong here or has the anonymous detection gone bad?

When I run it in a clean dotnet6 console app, I get slightly different errors:

Unable to compile template: yt0ad4nu.gs1(35,20): error CS1061: 'object' does not contain a definition for 'Name' and no accessible extension method 'Name' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
yt0ad4nu.gs1(35,33): error CS1061: 'object' does not contain a definition for 'Age' and no accessible extension method 'Age' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)

Generated class definition:

public class Template : ConsoleRunner6.RazorEngineCoreRunner.MyTemplate<System.Object>

Again using strongly typed type works fine. To me the problem looks like 2-fold, the old dotnet 4.8 works differently with Type.Attributes and when using dynamic model, the generated code does not reflect a dynamic type.

-EDIT- Just in case someone wonders the assembly references, I could not make it work by adding no assemblies, adding only needed assemblies or adding all possible assemblies. The error message is usually the same, but sometimes different. What's written above seemed like the most stable combination.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions