当查询结果集在下一页的末尾有一个链接时,为什么ODataFeed.NextPageLink为null?

时间:2013-11-04 21:57:53

标签: c# .net odata

我在网络浏览器中执行了一个查询,每页返回100个结果。此结果集最后有<link rel="next" href="...">,可以正确地将我引导到下一页结果。

但是,使用Microsoft的ODataLib的以下代码没有正确填写ODataFeed.NextPageLink,我试图了解原因。

下面的代码是从我的一个类中提取的单个方法,它只分配一个URI。我的ODataHttpRequestMessage类只是HttpWebRequest的包装,并返回响应作为IODataRequestMessage.GetStream的结果,并指定相同的Headers属性。

正确处理所有其他属性和链接,但不处理ODataFeed.NextPageLink

如何进一步排除问题或解决问题?

public void Go()
{
    ODataHttpRequestMessage request = new ODataHttpRequestMessage(this.Url);

    int count = 0;
    using (ODataMessageReader reader = new ODataMessageReader(request))
    {
        ODataReader feedReader = reader.CreateODataFeedReader();

        while (feedReader.Read())
        {
            switch (feedReader.State)
            {
                case ODataReaderState.NavigationLinkEnd:
                    ODataNavigationLink link = feedReader.Item as ODataNavigationLink;
                    break;

                case ODataReaderState.EntryEnd:
                    ODataEntry entry = feedReader.Item as ODataEntry;
                    count++;
                    break;

                case ODataReaderState.FeedEnd:
                    Microsoft.Data.OData.ODataFeed feed = feedReader.Item as Microsoft.Data.OData.ODataFeed;
                    break;
            }
        }
    }
}

以下是ODataHttpRequestMessage的实施:

internal sealed class ODataHttpRequestMessage : IODataRequestMessageAsync
{
    private readonly Uri url;
    private readonly HttpWebRequest request;
    private HttpWebResponse response;

    public Uri Url
    {
        get
        {
            return this.url;
        }

        set
        {
            throw new NotSupportedException("The url may not be changed once the request has been created.");
        }
    }

    public IEnumerable<KeyValuePair<string, string>> Headers
    {
        get
        {
            return this.response.Headers.ToLookup();
        }
    }

    public string Method
    {
        get
        {
            throw new NotImplementedException();
        }

        set
        {
            throw new NotImplementedException();
        }
    }

    public ODataHttpRequestMessage(Uri url)
    {
        this.url = url;
        this.request = HttpWebRequest.CreateHttp(url);
        this.request.Credentials = CredentialCache.DefaultNetworkCredentials;

        this.response = this.request.GetResponse() as HttpWebResponse;
    }

    public string GetHeader(string headerName)
    {
        return this.response.Headers[headerName];
    }

    public void SetHeader(string headerName, string headerValue)
    {
        this.request.Headers[headerName] = headerValue;
    }

    public Stream GetStream()
    {
        Stream stream = response.GetResponseStream();
        return stream;
    }

    public Task<Stream> GetStreamAsync()
    {
        Stream stream = this.GetStream();
        return Task.FromResult<Stream>(stream);
    }
}

在有效载荷的末尾,我提到了下一页的链接。 这是一个最小的有效负载,它可以证明这一点并导致问题:

<?xml version="1.0" encoding="utf-8"?>
<feed xml:base="http://a.b.c.d.e.com/service.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
    <id>http://a.b.c.d.e.com/Service.svc/Something</id>
    <title type="text">Something</title>
    <updated>2013-11-05T15:55:25Z</updated>
    <link rel="self" title="Something" href="Something" />
    <entry>
        <id>http://a.b.c.d.e.com/service.svc/Something('801b0100-1cee-430c-9767-febc4a4ad1e6')</id>
        <category term="IdentityItem.Something" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
        <link rel="edit" title="Something" href="Something('801b0100-1cee-430c-9767-febc4a4ad1e6')" />
        <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/MemberOf" type="application/atom+xml;type=feed" title="MemberOf" href="Something('801b0100-1cee-430c-9767-febc4a4ad1e6')/MemberOf" />
        <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/UserOwners" type="application/atom+xml;type=feed" title="UserOwners" href="Something('801b0100-1cee-430c-9767-febc4a4ad1e6')/UserOwners" />
        <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ServiceUserOwners" type="application/atom+xml;type=feed" title="ServiceUserOwners" href="Something('801b0100-1cee-430c-9767-febc4a4ad1e6')/ServiceUserOwners" />
        <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/MemberUsers" type="application/atom+xml;type=feed" title="MemberUsers" href="Something('801b0100-1cee-430c-9767-febc4a4ad1e6')/MemberUsers" />
        <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/MemberServiceUsers" type="application/atom+xml;type=feed" title="MemberServiceUsers" href="Something('801b0100-1cee-430c-9767-febc4a4ad1e6')/MemberServiceUsers" />
        <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/MemberTeams" type="application/atom+xml;type=feed" title="MemberTeams" href="Something('801b0100-1cee-430c-9767-febc4a4ad1e6')/MemberTeams" />
        <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Children" type="application/atom+xml;type=feed" title="Children" href="Something('801b0100-1cee-430c-9767-febc4a4ad1e6')/Children" />
        <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/BusinessRole" type="application/atom+xml;type=entry" title="BusinessRole" href="Something('801b0100-1cee-430c-9767-febc4a4ad1e6')/BusinessRole" />
        <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/RoleAssignments" type="application/atom+xml;type=feed" title="RoleAssignments" href="Something('801b0100-1cee-430c-9767-febc4a4ad1e6')/RoleAssignments" />
        <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/SuggestedDelegateFor" type="application/atom+xml;type=feed" title="SuggestedDelegateFor" href="Something('801b0100-1cee-430c-9767-febc4a4ad1e6')/SuggestedDelegateFor" />
        <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/EscalationSchedules" type="application/atom+xml;type=feed" title="EscalationSchedules" href="Something('801b0100-1cee-430c-9767-febc4a4ad1e6')/EscalationSchedules" />
        <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/CommunicationMethods" type="application/atom+xml;type=feed" title="CommunicationMethods" href="Something('801b0100-1cee-430c-9767-febc4a4ad1e6')/CommunicationMethods" />
        <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="Something('801b0100-1cee-430c-9767-febc4a4ad1e6')/Parent" />
        <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/PrimaryForUsers" type="application/atom+xml;type=feed" title="PrimaryForUsers" href="Something('801b0100-1cee-430c-9767-febc4a4ad1e6')/PrimaryForUsers" />
        <title />
        <updated>2013-11-05T15:55:25Z</updated>
        <author>
            <name />
        </author>
        <content type="application/xml">
            <m:properties>
                <d:Id>801b0100-1cee-430c-9767-febc4a4ad1e6</d:Id>
                <d:DisplayName>A Great Something</d:DisplayName>
                <d:ParentId>53ec9c58-c882-4a0b-8119-15cc517eee30</d:ParentId>
                <d:ParentNodeType>Something</d:ParentNodeType>
                <d:Tag m:null="true" />
                <d:Name>The name of a something</d:Name>
                <d:Created m:type="Edm.DateTime">2013-03-13T06:14:12Z</d:Created>
                <d:Modified m:type="Edm.DateTime">2013-10-11T03:42:32Z</d:Modified>
                <d:Description m:null="true" />
                <d:Status>Active</d:Status>
                <d:LegacyId m:type="Edm.Int32">2136</d:LegacyId>
                <d:BoundaryNodeType m:null="true" />
                <d:BoundaryNode m:type="IdentityItem.ExternalReference" m:null="true" />
                <d:IsDelegated m:type="Edm.Boolean">false</d:IsDelegated>
                <d:IsAnyRoleAssigned m:type="Edm.Boolean">true</d:IsAnyRoleAssigned>
                <d:Alias>An alias of something</d:Alias>
                <d:Category>Custom</d:Category>
                <d:BoundaryNodeId m:null="true" />
                <d:RelativePath>A relative path to a something</d:RelativePath>
            </m:properties>
        </content>
    </entry>
    <link rel="next" href="http://a.b.c.d.e.com/Service.svc/Something?$top=999900&amp;$skiptoken='19579'" />
</feed>

1 个答案:

答案 0 :(得分:1)

您将流视为请求消息而不是响应消息。由于您正在实现客户端,因此您将阅读响应并编写请求。请求有效负载不应具有下一个链接(因为请求是从客户端发送到服务器的,并且服务器永远不会遵循客户端生成的下一个链接),因此ODataLib读取器在读取请求时将忽略它。

ODataMessageReader构造函数可以将IODataResponseMessageIODataRequestMessage的实现作为参数。这确定ODataLib是否使用响应或请求读取规则读取消息。

而不是:

IODataRequestMessageAsync request = new ODataHttpRequestMessage(this.Url);

using (ODataMessageReader reader = new ODataMessageReader(request))
{
   ...
}

您的代码应该与此类似:

IODataResponseMessageAsync response = new ODataHttpResponseMessage();

using (ODataMessageReader reader = new ODataMessageReader(response))
{
   ...
}