FindReflectedAttributeType Object reference not set to an instance of an object.
ioanacro opened this issue · 20 comments
Hi,
I have this test that is joining Account entity with my custom entity Project. When I add a condition on account I get
Object reference not set to an instance of an object. error in FakeXrmEasy.XrmFakedContext.FindReflectedAttributeType
when calling RetrieveMultiple method.
[Test]
public void TestStandardEntities()
{
this.context = new XrmFakedContext();
var accountId = Guid.NewGuid();
var AccountToBeFound = new Account { Id = accountId, Name = "TestAccount", AccountId = accountId };
var ProjectToBeFound = new project
{
name = "TestProject",
projectId = Guid.NewGuid(),
projectcode = "someCode",
accountid = AccountToBeFound.ToEntityReference()
};
this.context.Initialize(new List<Entity> { AccountToBeFound, ProjectToBeFound });
this.service = this.context.GetOrganizationService();
var xml = @"<fetch count='10' distinct='true' page='1'>
<entity name='project'>
<attribute name='projectid' />
<filter type='or'>
<condition entityname='account' attribute='name' operator='like' value='TestAccount%' />
</filter>
<link-entity name='account' from='accountid' to='accountid'>
</link-entity>
</entity>
</fetch>";
var response = this.service.RetrieveMultiple(new FetchExpression(xml));
response.Entities.Count().Should().Be(1);
}
This query is working fine on the real CRM database. What object is null in this case?
Using 1.57.0.0 version
Another thing I noticed is if I change my condition to use another account attribute like accountratingcode
then I get System.Exception : XrmFakedContext.FindReflectedAttributeType: Attribute accountratingcode not found for type ...Models.project
Looks like the library is looking in my custom entity for those attributes.
Hi, latest version is 1.57.1, not sure if you tried that one and have the same issue there?
Also, could you check if the new attribute was generated (assuming you're generating early bound entities with crmsvcutil?)
I've update to latest version and re-run EarlyBound generator tool from XRMToolbox and the problem still persists.
Thanks @ioanacro ,
If you could please post the entire stack trace and the generated entities involved in this test, so the community might help? Otherwise it's going to be very difficult to reproduce.
Thanks!
Hi @jordimontana82 ,
ProjectTest.txt
Competitor.txt
test.txt
I've attached the generated entities, I used new ones only for testing purposes.
My guess from the 2 errors above is that earlyBoundType in FindReflectedAttributeType is wfp_ProjectClass instead of Competitor and propertyInfo ends up being null since everything is substracted from attributeName="name".
This is the stack trace:
System.NullReferenceException : Object reference not set to an instance of an object.
at FakeXrmEasy.XrmFakedContext.FindReflectedAttributeType(Type earlyBoundType, String sEntityName, String attributeName)
at FakeXrmEasy.Extensions.FetchXml.XmlExtensionsForFetchXml.GetConditionExpressionValueCast(String value, XrmFakedContext ctx, String sEntityName, String sAttributeName, ConditionOperator op)
at FakeXrmEasy.Extensions.FetchXml.XmlExtensionsForFetchXml.ToConditionExpression(XElement elem, XrmFakedContext ctx)
at FakeXrmEasy.Extensions.FetchXml.XmlExtensionsForFetchXml.<>c__DisplayClass21_0.b__3(XElement el)
at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext() at System.Collections.Generic.List
1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable
1 source)
at FakeXrmEasy.Extensions.FetchXml.XmlExtensionsForFetchXml.ToFilterExpression(XElement elem, XrmFakedContext ctx)
at FakeXrmEasy.Extensions.FetchXml.XmlExtensionsForFetchXml.<>c__DisplayClass16_0.b__1(XElement el)
at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable
1 source)
at FakeXrmEasy.Extensions.FetchXml.XmlExtensionsForFetchXml.ToCriteria(XDocument xlDoc, XrmFakedContext ctx)
at FakeXrmEasy.XrmFakedContext.TranslateFetchXmlDocumentToQueryExpression(XrmFakedContext context, XDocument xlDoc)
at FakeXrmEasy.FakeMessageExecutors.RetrieveMultipleRequestExecutor.Execute(OrganizationRequest req, XrmFakedContext ctx)
at FakeXrmEasy.XrmFakedContext.<>c__DisplayClass155_0.b__0(QueryBase req)
at FakeXrmEasy.XrmFakedContext.<>c__DisplayClass155_0.b__2(QueryBase req)
at FakeItEasy.Configuration.BuildableCallRule.Apply(IInterceptedFakeObjectCall fakeObjectCall) in C:\projects\fakeiteasy\src\FakeItEasy\Configuration\BuildableCallRule.cs:line 97
at FakeItEasy.Core.FakeManager.ApplyBestRule(IInterceptedFakeObjectCall fakeObjectCall) in C:\projects\fakeiteasy\src\FakeItEasy\Core\FakeManager.cs:line 261
at FakeItEasy.Core.FakeManager.FakeItEasy.Core.IFakeCallProcessor.Process(InterceptedFakeObjectCall fakeObjectCall) in C:\projects\fakeiteasy\src\FakeItEasy\Core\FakeManager.cs:line 173
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.ObjectProxy.RetrieveMultiple(QueryBase query)
In the FetchXml attached it seems you are trying to retrieve an attribute using the name of the entity instead of the attribute name:
<attribute name='{wfp_ProjectTest.EntityLogicalName}' />
@ioanacro Could you remove this bit to see if that works?
ou are trying to retrieve an attribute using the name of the entity instead of the attribute name:
Hey,
I still get 'Object reference not set to an instance of an object.' error with that line fixed or removed
[Test]
public void TestStandardEntities()
{
this.context = new XrmFakedContext();
var accountId = Guid.NewGuid();
var competitor = new Competitor { Id = accountId, Name = "something to look for" };
var project = new wfp_ProjectTest
{
wfp_Competitor = competitor.ToEntityReference(),
wfp_ProjectTestId = Guid.NewGuid()
};
this.context.Initialize(new List<Entity> { competitor, project });
this.service = this.context.GetOrganizationService();
var xml = $@"<fetch top='50' >
<entity name='{wfp_ProjectTest.EntityLogicalName}' >
<attribute name='{wfp_ProjectTest.EntityLogicalName}' />
<filter>
<condition entityname='{Competitor.EntityLogicalName}' attribute='name' operator='like' value='%something%' />
</filter>
<link-entity name='competitor' from='competitorid' to='wfp_appointment' />
</entity>
<entity name='{wfp_ProjectTest.EntityLogicalName}' >
<attribute name='{wfp_ProjectTest.Fields.wfp_ProjectTestId}' />
<filter>
<condition entityname='{Competitor.EntityLogicalName}' attribute='{Competitor.Fields.Name}' operator='like' value='%something%' />
</filter>
<link-entity name='{Competitor.EntityLogicalName}' from='{Competitor.Fields.CompetitorId}' to='{wfp_ProjectTest.Fields.wfp_Competitor}' />
</entity>
</fetch>";
var response = this.service.RetrieveMultiple(new FetchExpression(xml));
response.Entities.Count().Should().Be(1);
}
I don't think that specifying twice your entity
node in the FetchXML is supported in FakeXrmEasy
Good spot @BetimBeja That wasn't in the orignal bug at the top and I missed it @ioanacro .
Is that supported in the FetchXml schema even? I never seen a fetchXml with two entity nodes myself....
you are right! Bad copy&paste from the initial code:
I've modified the test to :
[Test]
public void TestStandardEntities()
{
this.context = new XrmFakedContext();
var accountId = Guid.NewGuid();
var competitor = new Competitor { Id = accountId, Name = "something to look for" };
var project = new wfp_ProjectTest
{
wfp_Competitor = competitor.ToEntityReference(),
wfp_ProjectTestId = Guid.NewGuid()
};
this.context.Initialize(new List<Entity> { competitor, project });
this.service = this.context.GetOrganizationService();
var xml = $@"<fetch top='50' >
<entity name='{wfp_ProjectTest.EntityLogicalName}' >
<attribute name='{wfp_ProjectTest.Fields.wfp_ProjectTestId}' />
<filter>
<condition entityname='{Competitor.EntityLogicalName}' attribute='{Competitor.Fields.Name}' operator='like' value='%something%' />
</filter>
<link-entity name='{Competitor.EntityLogicalName}' from='{Competitor.Fields.CompetitorId}' to='{wfp_ProjectTest.Fields.wfp_Competitor}' />
</entity>
</fetch>";
var response = this.service.RetrieveMultiple(new FetchExpression(xml));
response.Entities.Count().Should().Be(1);
}
But still getting the error
@jordimontana82 I think I found the bug.
fake-xrm-easy/FakeXrmEasy.Shared/XrmFakedContext.Queries.cs
Lines 183 to 194 in f294b9a
wfp_ProjectTest
entity and throws with a null reference in this line@jordimontana82 I think I found the bug.
fake-xrm-easy/FakeXrmEasy.Shared/XrmFakedContext.Queries.cs
Lines 183 to 194 in f294b9a
here in this part, there is a check, if the string ends with name, which is valid because it is looking for the name property, but it doesn't find it in the
wfp_ProjectTest
entity and throws with a null reference in this line
Hi @BetimBeja,
But why it looks in wfp_projectTest for the attribute name? the condition is on Competitor:
<condition entityname='{Competitor.EntityLogicalName}' attribute='{Competitor.Fields.Name}'...>
@jordimontana82 I faced the same problem, in my case, the problem is in this line
https://docs.microsoft.com/en-us/dotnet/api/system.type.basetype?view=net-5.0#remarks
I think you are creating Early Bound Entities with object
returning properties...
@BetimBeja yes, I created Early Bound Entities. But, it is not an object type.
[AttributeLogicalName("rr_unitcategories")]
public virtual IEnumerable<rr_UnitCategories> rr_UnitCategories { get; set; }
This property was autogenerated for multi-select optionset value
The point is I use EarlyBoundGenerator to generate this code and at the moment I did not find how to configure it for generating class instead of interface
@ioanacro Which early bound generator did you use? Just to check if it's really the same issue...
Hey, I'm also using EarlyBoundGenerator