Solved

Receiving error " 'object' does not contain a definition for 'ToList' ” when I am trying to create a List


Userlevel 7
Badge +8

Hello Everyone,

 

I have a method that I am calling them in different graphs. To make this happen I have used Reflection and dynamic parameters. a part of my method require creating a List of ApproveInfo. If I copy and paste my code to each graph it works just fine but when I call it in the Generic Method I am creating, raises the below error:

“Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: ''object' does not contain a definition for 'ToList''”

using PX.Api;
using PX.Common;
using PX.Data;
using PX.Data.EP;
using PX.Objects.EP;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using static UDApprovalWorkflow.EPApprovalAutomationHelper;



// I get error on the second line of my method
List<ApproveInfo> approvalSealedData = new List<ApproveInfo>();
approvalSealedData = Approval.GetApproversFromNextStep_Extension(Document, assignmentMap, stepBase.Sequence, Action).ToList();

 

What I am doing wrong? Any help is appreciated. As mentioned if I copy the method to each graph it works just fine.

icon

Best answer by aaghaei 17 August 2022, 17:43

View original

12 replies

Userlevel 5
Badge +1

Approval.GetApproversFromNextStep_Extension(Document, assignmentMap, stepBase.Sequence, Action) return an object type. You need to determine what its returning and cast it. Once you do the to list should work.

Userlevel 7
Badge +8

Thank @Shawn Burt it Actually returns the same “ApproveInfo”. Here is the class. As it pointed out earlier all works perfectly when I copy the code to each graph.

 

public virtual IEnumerable<ApproveInfo> GetApproversFromNextStep_Extension(SourceAssign Source, EPAssignmentMap AssignmentMap, int? CurrentStepSequence, string Action)
{
ApproveInfo approveInfo;

//Do stuff here

yield return approveInfo;
}

 

and below is part of the method I call the above:
 

public static EPApproval GetApprovalInfo(PXGraph Base, dynamic Document, EPApproval ApprovalBase, string Action, dynamic Approval)
{
// Do some stuff here

List<ApproveInfo> approvalSealedData = new List<ApproveInfo>();
// I Get error on the next line
approvalSealedData = Approval.GetApproversFromNextStep_Extension(Document, assignmentMap, stepBase.Sequence, Action).ToList();

// Do some stuff here
}

 

Hey  @markusray17  here again I am using Reflection to create a generic method that works for all graphs I need it for. You might be able to help here as well since it appears the similar issue of Cach.CreateCopy you healped with. The method works in each individual graph but not as generic one.

Userlevel 7
Badge +8

@laura01 @kbeatty21 @rosenjon @DConcannon @Gabriel Michaud I am reaching out as I stuck here. Can someone please help?

Userlevel 6
Badge +5
var test = Approval.GetApproversFromNextStep_Extension(Document, assignmentMap, stepBase.Sequence, Action).GetType();

Console.WriteLine("The type of this object is: " + test);

//do this inside GetApprovalInfo and post the result

@aaghaei - See above code. Run it in debug and tell us the result.

Userlevel 7
Badge +8

thank you @rosenjon for stepping up to help. Here is the error I receive

“The thread 0x7700 has exited with code 0 (0x0).” 

{Name = "<GetApproversFromNextStep_Extension>d__2" FullName = "UDApprovalWorkflow.EPApprovalAutomation_Extension`5+<GetApproversFromNextStep_Extension>d__2[[PX.Objects.AP.APInvoice, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APRegister+approved, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APRegister+rejected, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APInvoice+hold, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APSetupApproval, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}

 

 

  Name Value Type
  $exception error CS0103: The name '$exception' does not exist in the current context  
test {Name = "<GetApproversFromNextStep_Extension>d__2" FullName = "UDApprovalWorkflow.EPApprovalAutomation_Extension`5+<GetApproversFromNextStep_Extension>d__2[[PX.Objects.AP.APInvoice, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APRegister+approved, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APRegister+rejected, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APInvoice+hold, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APSetupApproval, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"} dynamic {System.RuntimeType}
  ▶ Assembly {UDApprovalWorkflow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null} System.Reflection.Assembly {System.Reflection.RuntimeAssembly}
  AssemblyQualifiedName "UDApprovalWorkflow.EPApprovalAutomation_Extension`5+<GetApproversFromNextStep_Extension>d__2[[PX.Objects.AP.APInvoice, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APRegister+approved, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APRegister+rejected, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APInvoice+hold, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APSetupApproval, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], UDApprovalWorkflow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" string
  Attributes NestedPrivate | Sealed | BeforeFieldInit System.Reflection.TypeAttributes
  ▶ BaseType {Name = "Object" FullName = "System.Object"} System.Type {System.RuntimeType}
  ContainsGenericParameters false bool
  ▶ CustomAttributes Count = 1 System.Collections.Generic.IEnumerable<System.Reflection.CustomAttributeData> {System.Collections.ObjectModel.ReadOnlyCollection<System.Reflection.CustomAttributeData>}
  ▶ DeclaredConstructors {System.Reflection.ConstructorInfo[1]} System.Collections.Generic.IEnumerable<System.Reflection.ConstructorInfo> {System.Reflection.ConstructorInfo[]}
  DeclaredEvents {System.Reflection.EventInfo[0]} System.Collections.Generic.IEnumerable<System.Reflection.EventInfo> {System.Reflection.EventInfo[]}
  ▶ DeclaredFields {System.Reflection.FieldInfo[23]} System.Collections.Generic.IEnumerable<System.Reflection.FieldInfo> {System.Reflection.FieldInfo[]}
  ▶ DeclaredMembers {System.Reflection.MemberInfo[36]} System.Collections.Generic.IEnumerable<System.Reflection.MemberInfo> {System.Reflection.MemberInfo[]}
  ▶ DeclaredMethods {System.Reflection.MethodInfo[10]} System.Collections.Generic.IEnumerable<System.Reflection.MethodInfo> {System.Reflection.MethodInfo[]}
  ▶ DeclaredNestedTypes {System.Reflection.TypeInfo.<get_DeclaredNestedTypes>d__23} System.Collections.Generic.IEnumerable<System.Reflection.TypeInfo> {System.Reflection.TypeInfo.<get_DeclaredNestedTypes>d__23}
  ▶ DeclaredProperties {System.Reflection.PropertyInfo[2]} System.Collections.Generic.IEnumerable<System.Reflection.PropertyInfo> {System.Reflection.PropertyInfo[]}
  ▶ DeclaringMethod '((System.RuntimeType)test).DeclaringMethod' threw an exception of type 'System.InvalidOperationException' System.Reflection.MethodBase {System.InvalidOperationException}
  ▶ DeclaringType {Name = "EPApprovalAutomation_Extension`5" FullName = "UDApprovalWorkflow.EPApprovalAutomation_Extension`5"} System.Type {System.RuntimeType}
  FullName "UDApprovalWorkflow.EPApprovalAutomation_Extension`5+<GetApproversFromNextStep_Extension>d__2[[PX.Objects.AP.APInvoice, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APRegister+approved, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APRegister+rejected, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APInvoice+hold, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APSetupApproval, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]" string
  ▶ GUID {b7e4ccd6-1818-3e52-b875-fb423689dbde} System.Guid
  ▶ GenericParameterAttributes '((System.RuntimeType)test).GenericParameterAttributes' threw an exception of type 'System.InvalidOperationException' System.Reflection.GenericParameterAttributes {System.InvalidOperationException}
  ▶ GenericParameterPosition '((System.RuntimeType)test).GenericParameterPosition' threw an exception of type 'System.InvalidOperationException' int {System.InvalidOperationException}
  ▶ GenericTypeArguments {System.Type[5]} System.Type[]
  GenericTypeParameters {System.Type[0]} System.Type[]
  HasElementType false bool
  ▶ ImplementedInterfaces {System.Type[5]} System.Collections.Generic.IEnumerable<System.Type> {System.Type[]}
  IsAbstract false bool
  IsAnsiClass true bool
  IsArray false bool
  IsAutoClass false bool
  IsAutoLayout true bool
  IsByRef false bool
  IsCOMObject false bool
  IsClass true bool
  IsConstructedGenericType true bool
  IsContextful false bool
  IsEnum false bool
  IsExplicitLayout false bool
  IsGenericParameter false bool
  IsGenericType true bool
  IsGenericTypeDefinition false bool
  IsImport false bool
  IsInterface false bool
  IsLayoutSequential false bool
  IsMarshalByRef false bool
  IsNested true bool
  IsNestedAssembly false bool
  IsNestedFamANDAssem false bool
  IsNestedFamORAssem false bool
  IsNestedFamily false bool
  IsNestedPrivate true bool
  IsNestedPublic false bool
  IsNotPublic false bool
  IsPointer false bool
  IsPrimitive false bool
  IsPublic false bool
  IsSealed true bool
  IsSecurityCritical true bool
  IsSecuritySafeCritical false bool
  IsSecurityTransparent false bool
  IsSerializable false bool
  IsSpecialName false bool
  IsUnicodeClass false bool
  IsValueType false bool
  IsVisible false bool
  MemberType NestedType System.Reflection.MemberTypes
  MetadataToken 33554509 int
  ▶ Module (System.Reflection.MemberInfo) {UDApprovalWorkflow.dll} System.Reflection.Module {System.Reflection.RuntimeModule}
  ▶ Module {UDApprovalWorkflow.dll} System.Reflection.Module {System.Reflection.RuntimeModule}
  Name "<GetApproversFromNextStep_Extension>d__2" string
  Namespace "UDApprovalWorkflow" string
  ▶ ReflectedType {Name = "EPApprovalAutomation_Extension`5" FullName = "UDApprovalWorkflow.EPApprovalAutomation_Extension`5"} System.Type {System.RuntimeType}
  ▶ StructLayoutAttribute {System.Runtime.InteropServices.StructLayoutAttribute} System.Runtime.InteropServices.StructLayoutAttribute
  ▶ TypeHandle {System.RuntimeTypeHandle} System.RuntimeTypeHandle
  ▶ TypeInitializer null System.Reflection.ConstructorInfo
  ▶ UnderlyingSystemType {Name = "<GetApproversFromNextStep_Extension>d__2" FullName = "UDApprovalWorkflow.EPApprovalAutomation_Extension`5+<GetApproversFromNextStep_Extension>d__2[[PX.Objects.AP.APInvoice, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APRegister+approved, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APRegister+rejected, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APInvoice+hold, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[PX.Objects.AP.APSetupApproval, PX.Objects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"} System.Type {System.RuntimeType}
  ▶ Static members    
  ▶ Non-Public members    
Userlevel 6
Badge +5

You’re going to have to post more of this code. For example, how is GetApprovalInfo being called?

I echo what Sean Burt said above...if you are going to use reflection, you need to understand the types you will be dealing with in your code. The abstraction has to be flexible enough to deal with the various object types that are going to be passed through your code. Also, I don’t think you are properly instantiating the Cache Extension… if Approval is the cache of some graph, then it should prob be something like this:

var test = Approval.GetExtension<GetApproversFromNextStep_Extension>(obj), where obj is some instance of that type. Again, you should probably be checking the types of the objects being passed if we’re using reflection (this is why your code works fine in individual class types, but not as a general abstraction).

I think this manner of trying to invoke the extension is probably just throwing an error, unless I’m missing some intermediate method you’ve created here...

Approval.GetApproversFromNextStep_Extension(Document, assignmentMap, stepBase.Sequence, Action)

 

Userlevel 6
Badge +5

i guess the other question I would have is how generalizable is this solution? How many workflow types are we really trying to modify with this code? Does it really require reflection in order to implement the solution you’re trying to create?

Badge +18

@aaghaei , I’m so flattered to be included… but I’m not a developer. 😐 Programming code isn’t one of my superpowers. Good luck!

Userlevel 7
Badge +8

@rosenjon thank you for elaborating.

  • Yes this well worth generalizing. So far I have 22 known screens/graphs that will use this. I have fully developped and implemented the full project for APBill and POOrder. Now that this is tested from begining of 2022 and stablized, next phase are to bring the remaining screens into the project.
  • The Approval in fact is Acumatica’s EPApprovalAutomation class which is called as follows in each screen that supports Assignment & Approval Map. My extension adds a few more methods to Acumatica’s class but it is called the sane way original class is called. Here is how “Approval” is called for example in APInvoiceEntry:
public EPApprovalAutomation_Extension<APInvoice, APInvoice.approved, APInvoice.rejected, APInvoice.hold, APSetupApproval> Approval;
  • This is how GetApprovalInfo called
EPApproval approvalNext = GetApprovalInfo(Base, document, approvalNext, EPActions.Pending);
  •  
Userlevel 6
Badge +2

@aaghaei Many moons ago I coded - maybe someday again. Until then here is my contribution - “look for a missing semicolon” ;)

Userlevel 7
Badge +8

@rosenjon @Chris Hackett 

One of my good friends, Hamed Oveisi, who always helps me with complicated issues provided the below replacement. All credit goes to him:

Erroneous Code:

List<ApproveInfo> approvalSealedData = Approval.GetApproversFromNextStep_Extension(Document, assignmentMap, stepBase.Sequence, Action).ToList();

Replacement Code:

List<ApproveInfo> approvalSealedData = ((IEnumerable)Approval.GetApproversFromNextStep_Extension(Document, assignmentMap, stepBase.Sequence, Action)).Cast<ApproveInfo>().ToList();

 

@Naveen Boga You always help me so I thought to loop you in that you might find it useful.

Userlevel 7
Badge +17

Thanks a lot for looping me @aaghaei  :)  

Reply


About Acumatica ERP system
Acumatica Cloud ERP provides the best business management solution for transforming your company to thrive in the new digital economy. Built on a future-proof platform with open architecture for rapid integrations, scalability, and ease of use, Acumatica delivers unparalleled value to small and midmarket organizations. Connected Business. Delivered.
© 2008 — 2024  Acumatica, Inc. All rights reserved