自定义wcf数据提供程序并调试关系错误

发布于 2024-12-08 18:32:01 字数 4007 浏览 0 评论 0原文

我正在实现一个自定义数据提供程序,我已经达到了它返回数据并且可以进行过滤的程度,但是在使关系正常工作方面遇到了一些麻烦。

查询元数据时,关系看起来正确,查询表时,会显示相关属性链接,但在尝试访问 ResourceReference 属性时,出现以下异常:

    Object reference not set to an instance of an object.
        System.NullReferenceException
        stacktrace at System.Data.Services.Providers.DataServiceProviderWrapper.GetResourceAssociationSet(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty)
   at System.Data.Services.Providers.DataServiceProviderWrapper.GetContainer(ResourceSetWrapper sourceContainer, ResourceType sourceResourceType, ResourceProperty navigationProperty)
   at System.Data.Services.Providers.DataServiceProviderWrapper.GetResourceProperties(ResourceSetWrapper resourceSet, ResourceType resourceType)
   at System.Data.Services.Serializers.SyndicationSerializer.WriteObjectProperties(IExpandedResult expanded, Object customObject, ResourceType resourceType, Uri absoluteUri, String relativeUri, SyndicationItem item, DictionaryContent content, EpmSourcePathSegment currentSourceRoot)
   at System.Data.Services.Serializers.SyndicationSerializer.WriteEntryElement(IExpandedResult expanded, Object element, ResourceType expectedType, Uri absoluteUri, String relativeUri, SyndicationItem target)
   at System.Data.Services.Serializers.SyndicationSerializer.WriteTopLevelElement(IExpandedResult expanded, Object element)
   at System.Data.Services.Serializers.Serializer.WriteRequest(IEnumerator queryResults, Boolean hasMoved)
   at System.Data.Services.ResponseBodyWriter.Write(Stream stream)

这是如何创建关系的示例:

var sourceReference = new ResourceProperty(
                relatedType.ResourceTypeName,
                ResourcePropertyKind.ResourceReference,
                relatedType.ResourceType);
            sourceReference.CanReflectOnInstanceTypeProperty = false;
            compoundType.ResourceType.AddProperty(sourceReference);

var destinationReference = new ResourceProperty(
                compoundType.ResourceSetName,
                ResourcePropertyKind.ResourceSetReference,
                compoundType.ResourceType);
            destinationReference.CanReflectOnInstanceTypeProperty = false;
            source.ResourceType.AddProperty(destinationReference);

var sourceAssociation = new ResourceAssociationSet(
                        "source",
                        new ResourceAssociationSetEnd(compoundType.ResourceSet, compoundType.ResourceType, sourceReference),
                        new ResourceAssociationSetEnd(relatedType.ResourceSet, relatedType.ResourceType, null));

var destinationAssociation = new ResourceAssociationSet(
                             "destination",
                             new ResourceAssociationSetEnd(relatedType.ResourceSet, relatedType.ResourceType, destinationReference),
                             new ResourceAssociationSetEnd(compoundType.ResourceSet, compoundType.ResourceType, null));

通过查看示例代码在 OData 网站上,我认为我已经正确完成了所有操作,但无法确定我的错误。有什么想法吗?或者有关调试自定义 WCF 数据服务的提示?

更新: 这是 null 异常之前发生的情况。

有一个与项目有关系的资源集 Collars,所以我执行以下查询: blah.svc/Collars(1)/Project

我对 IDataServiceMetadataProvider 中的 GetResourceAssociationSet 的重写被使用参数 ResourceSet = Collars、ResourceType = Collar、Property = Project 调用,并且返回上面指定的关联集。 然后再次使用 ResourceSet = Projects、ResourceType = Collar、Property = Project 调用 GetResourceAssociationSet,并且返回相同的关联集。

然后在System.Data.Services.Providers.GetResourceAssociationSetEnd中传入的变量是resourceSet = Projects,resourceType = Collar,resourceProperty = Project,这个函数返回null。

这使得 System.Data.Services.Providers.DataServiceProviderWrapper.GetResourceAssociationSet 中的 thisEnd 等于 null。 然后使用相同的变量调用 GetRelatedResourceAssociationSetEnd 并返回 null。

因此,它会因调用而崩溃,

ResourceSetWrapper relatedSet = this.ValidateResourceSet(relatedEnd.ResourceSet); 

因为 relatedEnd 为 null。

I'm implementing a custom data provider, I have gotten it to the point that it returns data and can be filtered, but am having some trouble getting relationships to work.

When querying the metadata the relationships look correct, and when querying a table the related property links appear, but when attempting to access a ResourceReference property I get the following exception:

    Object reference not set to an instance of an object.
        System.NullReferenceException
        stacktrace at System.Data.Services.Providers.DataServiceProviderWrapper.GetResourceAssociationSet(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty)
   at System.Data.Services.Providers.DataServiceProviderWrapper.GetContainer(ResourceSetWrapper sourceContainer, ResourceType sourceResourceType, ResourceProperty navigationProperty)
   at System.Data.Services.Providers.DataServiceProviderWrapper.GetResourceProperties(ResourceSetWrapper resourceSet, ResourceType resourceType)
   at System.Data.Services.Serializers.SyndicationSerializer.WriteObjectProperties(IExpandedResult expanded, Object customObject, ResourceType resourceType, Uri absoluteUri, String relativeUri, SyndicationItem item, DictionaryContent content, EpmSourcePathSegment currentSourceRoot)
   at System.Data.Services.Serializers.SyndicationSerializer.WriteEntryElement(IExpandedResult expanded, Object element, ResourceType expectedType, Uri absoluteUri, String relativeUri, SyndicationItem target)
   at System.Data.Services.Serializers.SyndicationSerializer.WriteTopLevelElement(IExpandedResult expanded, Object element)
   at System.Data.Services.Serializers.Serializer.WriteRequest(IEnumerator queryResults, Boolean hasMoved)
   at System.Data.Services.ResponseBodyWriter.Write(Stream stream)

Here's a sample of how I create the relationships:

var sourceReference = new ResourceProperty(
                relatedType.ResourceTypeName,
                ResourcePropertyKind.ResourceReference,
                relatedType.ResourceType);
            sourceReference.CanReflectOnInstanceTypeProperty = false;
            compoundType.ResourceType.AddProperty(sourceReference);

var destinationReference = new ResourceProperty(
                compoundType.ResourceSetName,
                ResourcePropertyKind.ResourceSetReference,
                compoundType.ResourceType);
            destinationReference.CanReflectOnInstanceTypeProperty = false;
            source.ResourceType.AddProperty(destinationReference);

var sourceAssociation = new ResourceAssociationSet(
                        "source",
                        new ResourceAssociationSetEnd(compoundType.ResourceSet, compoundType.ResourceType, sourceReference),
                        new ResourceAssociationSetEnd(relatedType.ResourceSet, relatedType.ResourceType, null));

var destinationAssociation = new ResourceAssociationSet(
                             "destination",
                             new ResourceAssociationSetEnd(relatedType.ResourceSet, relatedType.ResourceType, destinationReference),
                             new ResourceAssociationSetEnd(compoundType.ResourceSet, compoundType.ResourceType, null));

From looking at the sample code on the OData website I thought I'd done it all correctly, and cannot determine my error. Any ideas? or tips on debugging a custom WCF Data service?

Update:
Here's what happens just before the null exception.

Have a resource set Collars with a relationship to Projects so I do this query:
blah.svc/Collars(1)/Project

My override of GetResourceAssociationSet in my IDataServiceMetadataProvider gets called with the parameters ResourceSet = Collars, ResourceType = Collar, Property = Project and I return the association set specified above.
GetResourceAssociationSet is then called again with ResourceSet = Projects, ResourceType = Collar, Property = Project and I return the same association set.

Then in System.Data.Services.Providers.GetResourceAssociationSetEnd the variables passed in are resourceSet = Projects, resourceType = Collar, resourceProperty = Project, this function returns null.

Which makes thisEnd in System.Data.Services.Providers.DataServiceProviderWrapper.GetResourceAssociationSet equal to null.
Then GetRelatedResourceAssociationSetEnd is called with the same variables and also returns null.

So it then crashes with the call

ResourceSetWrapper relatedSet = this.ValidateResourceSet(relatedEnd.ResourceSet); 

because relatedEnd is null.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

遇见了你 2024-12-15 18:32:01

好吧,在我的调试中,我注意到在错误发生之前最后一次调用 GetResourceAssociationSet 是针对 resourcesSet 和 resourceType 参数具有不同值的情况(在派生类型的情况下)。

因此,我查看并发现了这个

WCF数据服务(OData),查询继承限制?

...你瞧,这个无信息的空引用异常(至少在我的情况下)是由同一问题引起的。我删除了有问题的属性(然后将其移至基础资源集,即使它实际上不存在),问题得到了解决。

有趣的旁注(如果这对原始海报有帮助):ResourceType.Properties 包括来自基本类型的属性。必须更改一些代码以使用 PropertiesDeclaredOnThisType 代替......

Well, in my debugging I noticed the last time GetResourceAssociationSet was called before the error occurred was for a case where the resourceSet and resourceType parameters had different values (in the case of a derived type).

So, I looked and found this

WCF data services (OData), query with inheritance limitation?

...and lo and behold this uninformative null reference exception (at least in my case) is caused by that same issue. I removed the offending property (and then moved it to the base resource set, even though it doesn't exist there in practice), and the issue was resolved.

Interesting side note (in case this helps the original poster): ResourceType.Properties includes properties from Base Types. Had to change some code to use PropertiesDeclaredOnThisType instead...

醉生梦死 2024-12-15 18:32:01

对我来说,解决方案是我在 IDataServiceQueryProvider 中实现 GetResourceType 时犯了一个错误。

当查询作为 ResourceSetReference 的资源属性时,我返回父资源的 ResourceType,而不是相关资源的类型。

The solution for me was that I had made a mistake in my implementation of GetResourceType in my IDataServiceQueryProvider.

When querying a Resource Property that was a ResourceSetReference I was returning the ResourceType of the parent resource, and not the type of the related resource.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文