我正在尝试从Java应用程序运行GetChanges方法(sitedata.asmx)。但是我无法弄清楚我必须通过的正确参数。这适用于SharePoint 2010。
通过查看service protocol specification,我看到这是必需的参数:
objectType:更改跟踪空间 也要报告 “ContentDatabase”或“SiteCollection”。 所有其他objectType值,如 在2.2.5.3节中定义,不得 使用。注意“网站”中的 实际上这个参数的上下文 是指网站集。
contentDatabaseId:内容的GUID 数据库,事先知道或获得 通过GetContent请求。
LastChangeId:指定起点的标记 对于要求的变更报告。 通常协议客户端获取 这个值来自对a的响应 以前的GetContent或GetChanges操作。
CurrentChangeId:指定的令牌 请求更改的端点 报告。如果不为空,则为CurrentChangeId 必须是从中获得的有效令牌 对之前GetChanges的响应 操作。通常,这个元素是 空; empty指定了 协议客户端请求所有更改 从起点开始到 现在的时间。
超时:值 这决定了有多少变化 应该在当前获取 操作。这个值必须更大 超过0和协议服务器必须 仅获取总变化的x% 默认情况下获取,其中x为 (超时除以30000)。
协议客户端必须传递令牌 对应于更改跟踪 objectType和。指定的空间 SOAP请求的目标URL。
我发送的SOAP In消息如下:
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Body>
<ns1:GetChanges xmlns:ns1="http://schemas.microsoft.com/sharepoint/soap/">
<ns1:objectType>SiteCollection</ns1:objectType>
<ns1:contentDatabaseId>E5C5E20A-5A9F-406C-B9F6-28923750CECD</ns1:contentDatabaseId>
<ns1:startChangeId>1;0;E5C5E20A-5A9F-406C-B9F6-28923750CECD;634438121498470000;46852</ns1:startChangeId>
<ns1:Timeout>0</ns1:Timeout>
</ns1:GetChanges>
</soapenv:Body>
</soapenv:Envelope>
但是我收到了这个回复:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<soap:Code>
<soap:Value>soap:Receiver</soap:Value>
</soap:Code>
<soap:Reason>
<soap:Text xml:lang="en">Exception of type 'Microsoft.SharePoint.SoapServer.SoapServerException' was thrown.</soap:Text>
</soap:Reason>
<detail>
<errorstring xmlns="http://schemas.microsoft.com/sharepoint/soap/">Object reference not set to an instance of an object.</errorstring>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
从SharePoint(位于Program Files \ Common Files \ Microsoft Shared \ Web Server Extensions \ 14 \ LOGS)检查日志,发现以下异常:
SOAP exception: System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.SharePoint.SPChangeToken.ParseChangeToken(String strChangeToken)
at Microsoft.SharePoint.SPChangeToken..ctor(String strChangeToken)
at Microsoft.SharePoint.SoapServer.SiteDataImpl.GetChanges(ObjectType objectType, String contentDatabaseId, String& startChangeId, String& endChangeId, Int64 maxChangesToFetch, UInt32 maxSPRequests, Boolean getMetadata, Boolean ignoreSecurityIfInherit, Int32 schemaVersion, Boolean& moreChanges)
at Microsoft.SharePoint.SoapServer.SiteDataImpl.GetChanges(ObjectType objectType, String contentDatabaseId, String& startChangeId, String& endChangeId, Int32 Timeout, Boolean& moreChanges)
at Microsoft.SharePoint.SoapServer.SiteData.GetChanges(ObjectType objectType, String contentDatabaseId, String& LastChangeId, String& CurrentChangeId, Int32 Timeout, Boolean& moreChanges)
但是,我无法找到任何对该错误的引用。我甚至无法从SPChangeToken类(http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spchangetoken_methods.aspx)找到ParseChangeToken方法,所以这很令人困惑。
我已经看到了这个问题,但这并没有解决我的问题:Other question
有人可以帮我正确调用此网络服务吗?
修改
尝试从C#应用程序调用它来确定问题不在于Java。这是代码:
SiteData.SiteDataSoapClient siteDataService = new SiteData.SiteDataSoapClient();
siteDataService.Endpoint.Address = new System.ServiceModel.EndpointAddress("URL/_vti_bin/sitedata.asmx");
siteDataService.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential("username", "password", "domain");
siteDataService.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
String startChangeId = "1;1;69d025ce-96a7-4131-adc0-7da1603e8d24;634439002539570000;46914";
String endChangeId = "";
bool hasMoreChanges = false;
String databaseID = E5C5E20A-5A9F-406C-B9F6-28923750CECD; //Got it by querying SharePoint database. Any idea how to get it programatically?
String result = siteDataService.GetChanges(SiteData.ObjectType.SiteCollection, databaseID, ref startChangeId, ref endChangeId, 0, out hasMoreChanges);
return result;
但是,我收到了'Microsoft.SharePoint.SoapServer.SoapServerException',此异常的详细信息为null。使用Fiddler监视SharePoint服务器返回的XML,并找到相同的“对象引用未设置为对象的实例”异常。
所以这肯定意味着我传递的参数有问题,对吗?
谢谢!
修改
如果有人感兴趣,我也通过在XML消息中将StartChangeId设置为LastChangeId并将EndChangeId设置为CurrentChangeId来完成此工作。
答案 0 :(得分:0)
解决了它。通过检查SharePoint日志,我注意到以下几行:
06/20/2011 08:24:03.80 w3wp.exe (0x1C2C) 0x0CAC SharePoint Foundation General fbs6 Medium <?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><GetChanges xmlns="http://schemas.microsoft.com/sharepoint/soap/"><objectType>SiteCollection</objectType><contentDatabaseId>{E5C5E20X-5A9F-406C-B9F6-28923750CECD}</contentDatabaseId><startChangeId></startChangeId><endChangeId>1;1;69c025ce-96a7-4131-adc0-7da1603e8d24;634439772069030000;47449</endChangeId><Timeout>0</Timeout></GetChanges></S:Body></S:Envelope> bafe1d43-e41c-47e9-bff2-5dc35a15298d
06/20/2011 08:24:03.80 w3wp.exe (0x1C2C) 0x0CAC SharePoint Foundation General 9ka5 Verbose GetChanges: objectType=SiteCollection, contentDbId={E5C5E20X-5A9F-406C-B9F6-28923750CECD}, startChange=, endChange=; MaxChanges=0, MaxSPRequests=50 bafe1d43-e41c-47e9-bff2-3dc35a15298d
请注意,在第二行,内容数据库Id由“{}”字符括起来。另外,请参阅从传入的XML中正确解析“contentDbId”,而“endChange”为空。第二个观察结果可能是导致“对象引用未设置为对象实例”异常的原因。那么,那个changeId出了什么问题?不知道,可能是XML编码有问题导致SharePoint无法正确解析changeId。
通过进一步查看相同的日志,我发现了这一行:
06/20/2011 08:42:54.35 w3wp.exe (0x1C2C) 0x2BC4 SharePoint Foundation General fbs6 Medium <?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body><ns1:GetChangesEx xmlns:ns1="http://schemas.microsoft.com/sharepoint/soap/"><ns1:version>1</ns1:version><ns1:xmlInput><GetChanges><ObjectType>1</ObjectType><ContentDatabaseId>{x4284f47-f050-4fe9-b7e9-caf8f4b882b0}</ContentDatabaseId><StartChangeId>1;0;x4284f47-f050-4fe9-b7e9-caf8f4b882b0;634441572386370000;72973</StartChangeId><EndChangeId /><RequestLoad>100</RequestLoad><GetMetadata>False</GetMetadata><IgnoreSecurityIfInherit>True</IgnoreSecurityIfInherit></GetChanges></ns1:xmlInput></ns1:GetChangesEx></soapenv:Body></soapenv:Envelope> fa5ab5a7-2e27-4e78-aa1f-b027ca3b120f
06/20/2011 08:42:54.35 w3wp.exe (0x1C2C) 0x2BC4 SharePoint Foundation General 9ka5 Verbose GetChanges: objectType=ContentDatabase, contentDbId={x4284f47-f050-4fe9-b7e9-caf8f4b882b0}, startChange=1;0;x4284f47-f050-4fe9-b7e9-caf8f4b882b0;634441572386370000;72973, endChange=; MaxChanges=500, MaxSPRequests=50 fa5ab5b7-2e27-4e78-aa1f-b027ca3b120f
这里,从传入的XML中正确解析了changeId。所以,我从GetChanges()方法更改为GetChangesEx(),传递了我在前一次调用时使用的完全相同的参数,并且它正常工作!我的猜测是,因为参数是在SOAP In请求的元素内编码的,所以Web Service能够正确地解析它们。
这是最终的SOAP In消息(格式化):
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Body>
<ns1:GetChangesEx xmlns:ns1="http://schemas.microsoft.com/sharepoint/soap/">
<ns1:version>1</ns1:version>
<ns1:xmlInput><GetChanges><ObjectType>7</ObjectType><ContentDatabaseId>{X5C5E20A-5A9F-406C-B9F6-28923750CECD}</ContentDatabaseId><StartChangeId>1;1;69f025ce-96a7-4131-adc0-7da1603e8d24;634439727021700000;47404</StartChangeId><EndChangeId>1;1;69d025ce-96a7-4131-adc0-7da1603e8b24;634441802456970000;47472</EndChangeId><RequestLoad>100</RequestLoad><GetMetadata>False</GetMetadata><IgnoreSecurityIfInherit>True</IgnoreSecurityIfInherit></GetChanges></ns1:xmlInput>
</ns1:GetChangesEx>
</soapenv:Body>
</soapenv:Envelope>
修改强>
C#代码示例:
SiteData.SiteDataSoapClient siteDataService = new SiteData.SiteDataSoapClient();
siteDataService.Endpoint.Address = new System.ServiceModel.EndpointAddress("URL/_vti_bin/sitedata.asmx");
siteDataService.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential("username", "password", "domain");
siteDataService.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
String xmlInput = "<GetChanges>" +
"<ObjectType>7</ObjectType>" +
"<ContentDatabaseId>{X5C5E20A-5A9F-406C-B9F6-28923750CECD}</ContentDatabaseId>" +
"<StartChangeId>1;1;69b025ce-96a7-4131-adc0-7da1603e8d24;634439727021700000;47404</StartChangeId>" +
"<EndChangeId>1;1;69b025ce-96a7-4131-adc0-7da1603e8d24;634441802456970000;47472</EndChangeId>" +
"<RequestLoad>100</RequestLoad>" +
"<GetMetadata>False</GetMetadata>" +
"<IgnoreSecurityIfInherit>True</IgnoreSecurityIfInherit>" +
"</GetChanges>";
String result = siteDataService.GetChangesEx(1, xmlInput);