如何从 SiteData.asmx Web 服务 (SharePoint 2010) 调用 GetChanges() 方法? [英] How to call GetChanges() method from SiteData.asmx web service (SharePoint 2010)?

查看:60
本文介绍了如何从 SiteData.asmx Web 服务 (SharePoint 2010) 调用 GetChanges() 方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从 Java 应用程序运行 GetChanges 方法 (sitedata.asmx).但是我无法弄清楚我必须传递的正确参数.这适用于 SharePoint 2010.

I'm trying to run GetChanges method (sitedata.asmx) from a Java application. However I can't figure out the correct parameters I must pass. This is for SharePoint 2010.

通过检查 服务协议规范,我看到这是必须的参数:

By checking on the service protocol specification, I saw this are the required parameters:

objectType:更改跟踪空间报告,或者内容数据库"或网站集".所有其他 objectType 值,如在第 2.2.5.3 节中定义,不得使用.请注意,站点"在里面这个参数的上下文实际上表示网站集.

objectType: The change tracking space to report about, either "ContentDatabase" or "SiteCollection". All other objectType values, as defined in section 2.2.5.3, MUST NOT be used. Note that "Site" in the context of this parameter actually means site collection.

contentDatabaseId: 内容的 GUID数据库,预先知道或获得通过 GetContent 请求.

contentDatabaseId: GUID of the content database, known in advance or obtained by GetContent request.

LastChangeId: 指定起点的标记对于请求的更改报告.通常协议客户端获取这个值来自对一个的响应之前的 GetContent 或 GetChanges 操作.

LastChangeId: A token specifying the starting point for the requested change report. Normally the protocol client obtains this value from the response to a previous GetContent or GetChanges operation.

CurrentChangeId: 指定的令牌请求更改的端点报告.如果不为空,则 CurrentChangeId必须是从对先前 GetChanges 的响应手术.通常,这个元素是空的;空指定协议客户端请求所有更改从起点开始直到现在的时间.

CurrentChangeId: A token specifying the endpoint for the requested change report. If not empty, CurrentChangeId must be a valid token obtained from the response to a previous GetChanges operation. Normally, this element is empty; empty specifies that the protocol client requests all changes starting from the starting point up to the present time.

超时:一个值这决定了多少变化应该在当前获取手术.这个值必须更大大于 0 并且协议服务器必须仅获取总更改的 x%默认情况下获取,其中 x 是(超时除以 30000).

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).

协议客户端必须传递令牌对应变更追踪由 objectType 指定的空间和SOAP 请求的目标 URL.

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.

我发送的 SOAP In 消息如下:

The SOAP In message I'm sending is as follows:

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

检查来自 SharePoint 的日志(位于 Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\LOGS),发现以下异常:

Checked the logs from SharePoint (located at Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\LOGS) and found the following exception:

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 类中找到方法 ParseChangeToken (http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spchangetoken_methods.aspx),所以这令人困惑.

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.

我已经看到了这个问题,但这并没有解决我的问题:其他问题

I already saw this question, however this doesn't solve my issue: Other question

谁能帮我正确调用这个网络服务?

Can anyone help me calling this web service correctly?

编辑

尝试从 C# 应用程序调用它以确定问题不在于 Java.这是代码:

Tried calling it from a C# application to determine that the issue is not with 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;

但是,我收到了Microsoft.SharePoint.SoapServer.SoapServerException",并且此异常的详细信息为空.使用Fiddler 窥探SharePoint服务器返回的XML,发现同样的'Object reference not设置为对象异常的实例.

However, I got 'Microsoft.SharePoint.SoapServer.SoapServerException' and the detail of this exception is 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.

所以这肯定意味着我传递的参数有问题,对吗?

So this certainly means there is something wrong with the parameters I'm passing, right?

谢谢!!

编辑

如果有人感兴趣,我也通过在 XML 消息中将 StartChangeId 设置为 LastChangeId 并将 EndChangeId 设置为 CurrentChangeId 来完成这项工作.

If someone is interested, I made this work too by setting StartChangeId to LastChangeId and EndChangeId to CurrentChangeId in the XML message.

推荐答案

解决了.通过检查 SharePoint 日志,我注意到以下几行:

Solved it. By checking on the SharePoint logs, I noticed the following lines:

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.

Notice on the second line, that the content database Id is enclosed by "{}" characters. Also, see that "contentDbId" is parsed correctly from the incoming XML, while "endChange" is empty. 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? No idea, probably there is something wrong with the XML encoding that prevents SharePoint from parsing the changeId correctly.

通过进一步查看同一日志,我发现了以下几行:

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

这里,changeId 是从传入的 XML 中正确解析出来的.所以,我从 GetChanges() 方法更改为 GetChangesEx(),传递了我在前一次调用中使用的完全相同的参数,并且它工作正常!!我的猜测是,因为参数被编码在 SOAP In 请求的一个元素中,所以 Web Service 能够正确解析它们.

Here, the changeId is correctly parsed from the incoming 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!! 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 消息(格式化):

Here is the final SOAP In message (formatted):

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

编辑

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);

这篇关于如何从 SiteData.asmx Web 服务 (SharePoint 2010) 调用 GetChanges() 方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆