2011-06-16 88 views
0

我想從Java應用程序運行GetChanges方法(sitedata.asmx)。但是我無法弄清楚我必須通過的正確參數。這是SharePoint 2010的如何從SiteData.asmx Web服務(SharePoint 2010)調用GetChanges()方法?

通過對service protocol specification檢查,只見這是必需的參數:

的objectType:變化跟蹤空間 報告有關,無論是 「ContentDatabase」或「 SiteCollection」。 所有其他objectType值,如第2.2.5.3節中定義的 ,不得使用 。請注意,該參數的 上下文中的「網站」實際上是 意味着網站集。

contentDatabaseId: GUID內容 數據庫,預先已知或通過請求的getContent獲得 的。

LastChangeId:令牌,指定所請求的更改報告的起始點 。 通常,協議客戶端從以前的GetContent或GetChanges操作對 的響應中獲得該值。

CurrentChangeId:令牌指定 請求的更改 報告的端點。如果不爲空,則CurrentChangeId 必須是從 獲得的對前一個GetChanges 操作的響應中獲得的有效令牌。通常情況下,這個元素是 爲空;空指定 協議客戶端請求從起始點開始到目前爲止的所有更改 到 。

超時:,它確定如何許多變化 應該在當前 操作可讀取的值 。該值必須比0大 ,並且協議服務器必須獲取 默認獲取的總變化的x%,其中x是 (超時除以30000)。

該協議客戶端必須傳遞 對應於變化跟蹤由指定的objectType空間 和 SOAP請求的目標URL令牌。

的SOAP消息中,我發送如下:

<?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文件\共同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

誰能幫助我正確地調用這個Web服務?

編輯

嘗試從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」,這異常的細節是零。使用Fiddler來窺探SharePoint服務器返回的XML,並發現相同的「對象引用未設置爲對象的實例」異常。

所以這肯定意味着我傳遞的參數有問題,對吧?

謝謝!

編輯

如果有人有興趣,我通過StartChangeId設置爲LastChangeId和EndChangeId XML消息中CurrentChangeId做這項工作了。

回答

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>&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能夠正確解析它們。

下面是最終SOAP消息中(格式化):

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