-
Notifications
You must be signed in to change notification settings - Fork 92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RazorEngineCore.ObjectExtenders.IsAnonymous(this object obj) not recognizing dynamic or anonymous types #135
Comments
I might add, the results are inconsistent across runtimes and the way these methods are called. I copied the
|
Hi, may I ask you to post a sample code to reporoduce this problem, like you did in first message. if you pass dynamic into generic method, it should be wrapped, see https://www.codeproject.com/Articles/5260233/Building-String-Razor-Template-Engine-with-Bare-Ha IsAnonymous supposed to check the instance, not a type, public static bool IsAnonymous(this object obj)
{
Type type = obj.GetType();
return Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false)
&& type.IsGenericType && type.Name.Contains("AnonymousType")
&& (type.Name.StartsWith("<>") || type.Name.StartsWith("VB$"))
&& type.Attributes.HasFlag(TypeAttributes.NotPublic);
} |
Thanks for your reply. Here is some sample code from my testing project. I first copied the decompiled IsAnonymous() into my code and added some formatting:
The first statement is clear, it gets type of the obj. That's my bad, I didn't notice it at first. Then I run this much code:
But the line that says throws, throws a Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: '<>f__AnonymousType0<string,int>' does not contain a definition for 'IsAnonymous'. This is caused by the fact that you cannot call extension methods with objects that are defined with dynamic-keyword. That's also what lead me to thinking that the IsAnonymous is not supposed to be called with the object itself. Now if I pass those models into a generic method where the generic parameter is for the model, IsAnonymous seems to work on each of the models and give correct results when called on the object, thanks for pointing it out. But it throws errors from template compile as it is in my first post. I have not previously learned that I need the AnonymousTypeWrapper and also I need to use a non-generic Template for compiling ( With this info I would suggest two things. 1) better documentation about how to use dynamic and anonymous types. There are no /// XML comments in the code? 2) Maybe automate the use of AnonymousTypeWrapper? |
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:Error is thrown when calling Compile<>:
Line 35 in generated code:
Creation of model:
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 propertiestype.IsPublic
= false andtype.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:
Generated class definition:
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.
The text was updated successfully, but these errors were encountered: