Как вызвать метод GetChanges () из веб-службы SiteData.asmx (SharePoint 2010)? - PullRequest
0 голосов
/ 17 июня 2011

Я пытаюсь запустить метод GetChanges (sitedata.asmx) из приложения Java.Однако я не могу понять правильные параметры, которые я должен передать.Это для SharePoint 2010.

При проверке спецификации протокола службы я обнаружил, что это обязательные параметры:

objectType: Пространство отслеживания изменений, о котором нужно сообщать, либо «ContentDatabase», либо «SiteCollection».Все другие значения objectType, определенные в разделе 2.2.5.3, НЕ ДОЛЖНЫ использоваться.Обратите внимание, что «Сайт» в контексте этого параметра фактически означает семейство сайтов.

contentDatabaseId: GUID базы данных контента, заранее известной или полученной по запросу GetContent.

LastChangeId: Токен, указывающий начальную точку для запрошенного отчета об изменениях.Обычно клиент протокола получает это значение из ответа на предыдущую операцию GetContent или GetChanges.

CurrentChangeId: Маркер, указывающий конечную точку для запрошенного отчета об изменениях.Если не пустой, CurrentChangeId должен быть действительным токеном, полученным из ответа на предыдущую операцию GetChanges.Обычно этот элемент пуст;empty указывает, что клиент протокола запрашивает все изменения, начиная с начальной точки до настоящего времени.

Тайм-аут: Значение, определяющее, сколько изменений следует извлечь в текущей операции.Это значение ДОЛЖНО быть больше 0, а сервер протокола ДОЛЖЕН извлекать только х% от общего числа изменений, которые выбраны по умолчанию, где х - это (Тайм-аут, разделенный на 30000).

Клиент протокола ДОЛЖЕН передавать токены, которые соответствуют пространству отслеживания изменений, указанному в objectType, и целевой URL-адрес SOAP-запроса.

Отправляемое сообщение 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 \ Расширения веб-сервера \ 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)

Однако я не могу найти никаких ссылок на эту ошибку.Я даже не могу найти метод ParseChangeToken из класса SPChangeToken (http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spchangetoken_methods.aspx),, так что это сбивает с толку.

Я уже видел этот вопрос, однако это не решает мою проблему: Другой вопрос

Может ли кто-нибудь помочь мне правильно вызвать этот веб-сервис?

РЕДАКТИРОВАТЬ

Попытался вызвать его из приложения 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 дляшпионить за XML, возвращаемым сервером SharePoint, и обнаружил ту же исключительную ситуацию: «Ссылка на объект не установлена ​​для экземпляра объекта».

Так что это, безусловно, означает, что что-то не так с параметрами, которые я передаю,да?

Спасибо !!

Редактировать

Если кому-то интересно, я тоже сделал эту работу, установив StartChangeId в LastChangeId и EndChangeId в CurrentChangeИдентификатор в сообщении XML.

1 Ответ

0 голосов
/ 21 июня 2011

Решил это.Проверяя журналы 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 базы данных контента заключен в символы "{}".Также обратите внимание, что «contentDbId» правильно анализируется из входящего XML, а «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, веб-служба может их правильно проанализировать.

Вот последнее сообщение 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>

Редактировать

Пример кода 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);
...