简体   繁体   English

如何从SiteData.asmx Web服务(SharePoint 2010)调用GetChanges()方法?

[英]How to call GetChanges() method from SiteData.asmx web service (SharePoint 2010)?

I'm trying to run GetChanges method (sitedata.asmx) from a Java application. 我正在尝试从Java应用程序运行GetChanges方法(sitedata.asmx)。 However I can't figure out the correct parameters I must pass. 但是我无法弄清楚必须传递的正确参数。 This is for SharePoint 2010. 这用于SharePoint 2010。

By checking on the service protocol specification , I saw this are the required parameters: 通过检查服务协议规范 ,我看到这是必需的参数:

objectType: The change tracking space to report about, either "ContentDatabase" or "SiteCollection". objectType:要报告的更改跟踪空间,即“ ContentDatabase”或“ SiteCollection”。 All other objectType values, as defined in section 2.2.5.3, MUST NOT be used. 不得使用第2.2.5.3节中定义的所有其他objectType值。 Note that "Site" in the context of this parameter actually means site collection. 请注意,此参数上下文中的“站点”实际上是网站集。

contentDatabaseId: GUID of the content database, known in advance or obtained by GetContent request. contentDatabaseId:内容数据库的GUID,事先已知或由GetContent请求获得。

LastChangeId: A token specifying the starting point for the requested change report. LastChangeId:一个令牌,用于指定请求的更改报告的起点。 Normally the protocol client obtains this value from the response to a previous GetContent or GetChanges operation. 通常,协议客户端从对先前GetContent或GetChanges操作的响应中获取此值。

CurrentChangeId: A token specifying the endpoint for the requested change report. CurrentChangeId:一个令牌,用于指定请求的更改报告的端点。 If not empty, CurrentChangeId must be a valid token obtained from the response to a previous GetChanges operation. 如果不为空,则CurrentChangeId必须是从对先前GetChanges操作的响应中获得的有效令牌。 Normally, this element is empty; 通常,此元素为空; empty specifies that the protocol client requests all changes starting from the starting point up to the present time. empty指定协议客户端请求从起点到当前时间的所有更改。

Timeout: A value that determines how many changes should be fetched in the current operation. 超时:一个值,该值确定在当前操作中应获取多少更改。 This value MUST be greater than 0 and the protocol server MUST only fetch x% of total changes that are fetched by default, where x is (Timeout divided by 30000). 该值必须大于0,并且协议服务器务必仅获取默认情况下获取的总更改的x%,其中x为(超时除以30000)。

The protocol client MUST pass tokens that correspond to the change tracking space specified by the objectType and the target URL of the SOAP request. 协议客户端必须传递与由objectType和SOAP请求的目标URL指定的更改跟踪空间相对应的令牌。

The SOAP In message I'm sending is as follows: 我要发送的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>

However I get this response: 但是我得到这个回应:

<?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>

Checked the logs from SharePoint (located at Program Files\\Common Files\\Microsoft Shared\\Web Server Extensions\\14\\LOGS) and found the following exception: 从SharePoint检查日志(位于Program Files \\ Common Files \\ Microsoft Shared \\ Web服务器扩展\\ 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)

However, I'm not able to find any references to that error. 但是,我找不到对该错误的任何引用。 I can't even found the method ParseChangeToken from SPChangeToken class ( http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spchangetoken_methods.aspx ), so this is confusing. 我什至没有从SPChangeToken类( http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spchangetoken_methods.aspx )中找到ParseChangeToken方法,所以这令人困惑。

I already saw this question, however this doesn't solve my issue: Other question 我已经看到了这个问题,但是这并不能解决我的问题: 其他问题

Can anyone help me calling this web service correctly? 谁能帮助我正确调用此Web服务?

EDIT 编辑

Tried calling it from a C# application to determine that the issue is not with Java. 尝试从C#应用程序对其进行调用,以确定问题不在于Java。 This is the code: 这是代码:

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;

However, I got 'Microsoft.SharePoint.SoapServer.SoapServerException' and the detail of this exception is null. 但是,我收到了“ Microsoft.SharePoint.SoapServer.SoapServerException”,此异常的详细信息为null。 Used Fiddler to spy on the XML returned by the SharePoint server, and found the same 'Object reference not set to an instance of an object' exception. 使用Fiddler监视SharePoint服务器返回的XML,并发现相同的“对象引用未设置为对象实例”异常。

So this certainly means there is something wrong with the parameters I'm passing, right? 所以这当然意味着我传递的参数有问题,对吧?

Thanks!! 谢谢!!

Edit 编辑

If someone is interested, I made this work too by setting StartChangeId to LastChangeId and EndChangeId to CurrentChangeId in the XML message. 如果有人感兴趣,我也通过在XML消息中将StartChangeId设置为LastChangeId并将EndChangeId设置为CurrentChangeId来完成这项工作。

Solved it. 解决了。 By checking on the SharePoint logs, I noticed the following lines: 通过检查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

Notice on the second line, that the content database Id is enclosed by "{}" characters. 请注意,在第二行中,内容数据库ID由“ {}”字符括起来。 Also, see that "contentDbId" is parsed correctly from the incoming XML, while "endChange" is empty. 另外,请参见从传入XML正确解析了“ contentDbId”,而“ endChange”为空。 This second observation, is probably what leads to the "Object reference not set to an instance of an object" exception. 第二个观察结果可能是导致“对象引用未设置为对象实例”的异常的原因。 So, what is wrong with that changeId? 那么,那个changeId有什么问题呢? No idea, probably there is something wrong with the XML encoding that prevents SharePoint from parsing the changeId correctly. 不知道,XML编码可能有问题,导致SharePoint无法正确解析changeId。

By further looking on the same log, I found this lines: 通过进一步查看同一日志,我发现了以下几行:

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>&lt;GetChanges>&lt;ObjectType>1&lt;/ObjectType>&lt;ContentDatabaseId>{x4284f47-f050-4fe9-b7e9-caf8f4b882b0}&lt;/ContentDatabaseId>&lt;StartChangeId>1;0;x4284f47-f050-4fe9-b7e9-caf8f4b882b0;634441572386370000;72973&lt;/StartChangeId>&lt;EndChangeId />&lt;RequestLoad>100&lt;/RequestLoad>&lt;GetMetadata>False&lt;/GetMetadata>&lt;IgnoreSecurityIfInherit>True&lt;/IgnoreSecurityIfInherit>&lt;/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

Here, the changeId is correctly parsed from the incoming XML. 在这里,changeId是从传入的XML中正确解析的。 So, I changed from GetChanges() method to GetChangesEx(), passed the exact same parameters I was using on the former call, and it worked correctly!! 因此,我从GetChanges()方法更改为GetChangesEx(),并传递了我在前一个调用中使用的完全相同的参数,并且它可以正常工作! My guess is that because the parameters are encoded inside an element of the SOAP In request, the Web Service is able to parse them correctly. 我的猜测是,由于参数是在SOAP In请求的元素内编码的,因此Web Service能够正确解析它们。

Here is the final SOAP In message (formatted): 这是最终的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>&lt;GetChanges>&lt;ObjectType>7&lt;/ObjectType>&lt;ContentDatabaseId>{X5C5E20A-5A9F-406C-B9F6-28923750CECD}&lt;/ContentDatabaseId>&lt;StartChangeId>1;1;69f025ce-96a7-4131-adc0-7da1603e8d24;634439727021700000;47404&lt;/StartChangeId>&lt;EndChangeId>1;1;69d025ce-96a7-4131-adc0-7da1603e8b24;634441802456970000;47472&lt;/EndChangeId>&lt;RequestLoad>100&lt;/RequestLoad>&lt;GetMetadata>False&lt;/GetMetadata>&lt;IgnoreSecurityIfInherit>True&lt;/IgnoreSecurityIfInherit>&lt;/GetChanges></ns1:xmlInput>
        </ns1:GetChangesEx>
    </soapenv:Body>
</soapenv:Envelope>

Edit 编辑

C# code example: 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM