C# 当查询结果集末尾有下一页的链接时,为什么ODataFeed.NextPageLink为空?
我在web浏览器中执行了一个查询,每页返回100个结果。这个结果集的末尾有一个C# 当查询结果集末尾有下一页的链接时,为什么ODataFeed.NextPageLink为空?,c#,.net,odata,C#,.net,Odata,我在web浏览器中执行了一个查询,每页返回100个结果。这个结果集的末尾有一个,它正确地引导我进入下一页的结果 但是,以下代码使用Microsoft的ODataLib,无法正确填写ODataFeed.NextPageLink,我正在试图理解原因 下面的代码是从我的一个类中提取的单个方法,它只分配一个URI。MyODataHttpRequestMessage类只是HttpWebRequest的包装器,返回响应作为IODataRequestMessage.GetStream的结果,并为其分配Head
,它正确地引导我进入下一页的结果
但是,以下代码使用Microsoft的ODataLib,无法正确填写ODataFeed.NextPageLink
,我正在试图理解原因
下面的代码是从我的一个类中提取的单个方法,它只分配一个URI。MyODataHttpRequestMessage
类只是HttpWebRequest
的包装器,返回响应作为IODataRequestMessage.GetStream的结果,并为其分配Header
属性
所有其他属性和链接都已正确处理,但未正确处理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);
}
}
内部密封类ODataHttpRequestMessage:IODataRequestMessageAsync
{
私有只读Uri url;
私有只读HttpWebRequest请求;
私有HttpWebResponse;
公共Uri Url
{
得到
{
返回this.url;
}
设置
{
抛出new NotSupportedException(“创建请求后,url可能不会更改。”);
}
}
公共IEnumerable标头
{
得到
{
返回this.response.Headers.ToLookup();
}
}
公共字符串方法
{
得到
{
抛出新的NotImplementedException();
}
设置
{
抛出新的NotImplementedException();
}
}
公共ODataHttpRequestMessage(Uri url)
{
this.url=url;
this.request=HttpWebRequest.CreateHttp(url);
this.request.Credentials=CredentialCache.DefaultNetworkCredentials;
this.response=this.request.GetResponse()作为HttpWebResponse;
}
公共字符串GetHeader(字符串头名称)
{
返回此.response.Headers[headerName];
}
public void SetHeader(字符串headerName、字符串headerValue)
{
this.request.Headers[headerName]=headerValue;
}
公共流GetStream()
{
Stream=response.GetResponseStream();
回流;
}
公共任务GetStreamAsync()
{
Stream=this.GetStream();
返回Task.FromResult(流);
}
}
在有效载荷的末尾,我提到有一个到下一页的链接。
下面是一个最小有效负载,它演示了这一点,也导致了问题:
<?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&$skiptoken='19579'" />
</feed>
http://a.b.c.d.e.com/Service.svc/Something
某物
2013-11-05T15:55:25Z
http://a.b.c.d.e.com/service.svc/Something('801b0100-1cee-430c-9767-febc4a4ad1e6')
2013-11-05T15:55:25Z
801b0100-1cee-430c-9767-febc4a4ad1e6
好东西
53ec9c58-c882-4a0b-8119-15cc517eee30
某物
某物的名字
2013-03-13T06:14:12Z
2013-10-11T03:42:32Z
活跃的
2136
假的
真的
某物的别名
习俗
指向某事物的相对路径
您将流视为请求消息而不是响应消息。因为您正在实现一个客户机,所以您将阅读响应和编写请求。请求有效负载不应该有下一个链接(因为请求是从客户端发送到服务器的,服务器永远不会跟随客户端生成的下一个链接),所以ODataLib读取器在读取请求时会忽略它
ODataMessageReader
构造函数可以将IODataResponseMessage
或IODataRequestMessage
的实现作为参数。这决定ODataLib是使用响应还是请求读取规则读取消息
与此相反:
IODataRequestMessageAsync request = new ODataHttpRequestMessage(this.Url);
using (ODataMessageReader reader = new ODataMessageReader(request))
{
...
}
您的代码应类似于以下内容:
IODataResponseMessageAsync response = new ODataHttpResponseMessage();
using (ODataMessageReader reader = new ODataMessageReader(response))
{
...
}
我没有看到任何明显的错误,但如果这是ODataLib中的一个bug,我会感到惊讶,因为这是一个非常常见的场景。你确定你是在FeedEnd检查而不是FeedStart?为了进一步调试,也许你可以试着简化你的测试负载,使其小而可复制,然后将负载发布到这里?@JenS我继续,并在那里添加了测试负载,它只是一个最初检索到100条记录的查询,但我去掉了下一个99条,保留了链接和提要端,并重写一些属性名称以使其模糊。好的,谢谢。我在下面添加了一个答案。我是黑客,并融合了请求和响应的功能。现在这是有道理的。我会确保它明天早上起作用,并接受解决方案,如果是这样的话,我想它会的。如果我是图书馆的作者,我会做的一件事是,当你访问该财产时抛出一个异常,指示在与请求关联时尝试获取或设置nextPackageLink
是无效的操作。