Конференция "Сети" » Получение списков SharePoint с дочерних сайтов
 
  • Rouse_ © (05.05.12 15:20) [0]
    В кратце проблема выглядит следующим образом:
    1. Есть SharePoint сервер (допустим адрес http://win2008sps)
    2. На сервере создана библиотека (TestLibrary1). Соответственно зайти в нее чрез браузер можно по адресу win2008sps/TestLibrary1.
    3. Так-же на сервере создан дочерний сайт test2 (адрес http://win2008sps/test2/)
    4. В нем создана библиотека TestLibrary2 (путь win2008sps/test2/TestLibrary2)

    Мне необходимо получить содержимое обоих сайтов.

    Делаю следующее:
    Через WSDL получил интерфейсы WebSoap  и ListSoap.
    Получаю список веб ресурсов при помощи WebsSoap.GetWebCollection. Он возвращает информацию о дочернем сайте test2 с его путем.
    Запоминаю путь и делаю следующее:
    При помощи ListsSoap.GetListCollection опрашиваю рутовый сервер, он возвращает список всего что у него есть, в том числе и информацию о TestLibrary1.
    После чего делаю такой-же запрос, но уже по адресу test2 сайта (http://win2008sps/test2/_vti_bin/Lists.asmx), но мне возвращаются данные опять-же с рутового сервера, а не с дочернего сайта.

    Вопрос, как получить список с дочернего сайта, а не с рута?
    Где я ошибаюсь, в своем коде, или нужно что-то настроить на самом SharePoint сервере?
  • Cobalt © (05.05.12 16:10) [1]
    Выпьем, няня, где же код? ;-)
  • Rouse_ © (05.05.12 16:19) [2]
    А зачем код? Он что-то даст?

    Ну на. смотри :)

     TSoapData = TDictionary<string, OleVariant>;
     TSoapDataList = TObjectList<TSoapData>;

     TFWSharePoint = class
     strict private type
       TSharePointAPIType = (atWebs, atLists, atCopy);
     strict private const
       HTTPPrefix = 'http://';
       URL_PREFIX = '%s/_vti_bin/';
       APITypeStrings: array [TSharePointAPIType] of string = (
         HTTPPrefix + URL_PREFIX + 'Webs.asmx',
         HTTPPrefix + URL_PREFIX + 'Lists.asmx',
         HTTPPrefix + URL_PREFIX + 'Copy.asmx'
       );
       procedure SetUrl(const Value: string);
     strict private
       FUrl, FUserName, FPassword: string;
     protected
       function GetRIO: THTTPRIO;
       function GetUrlString(const Path: string; APIType: TSharePointAPIType): string;
     public
       function GetWebSiteList: TSoapDataList;
       function GetLibraryList(const SharePointSrvAddr: string): TSoapDataList;
       function GetItemsList(const SharePointSrvAddr, ListName, Folder: string): TSoapDataList;
       property SharePointURL: string read FUrl write SetUrl;
       property UserName: string read FUserName write FUserName;
       property Password: string read FPassword write FPassword;
     end;

    implementation

    type
     TExtractURLAction = (eaLeaveOnlyURL, eaTrimLastSlash);
     TExtractURLActions = set of TExtractURLAction;

    function ExtractURL(URL: string; Actions: TExtractURLActions): string;
    var
     HttpPos, Len: Integer;
    begin
     URL := StringReplace(URL, '\', '/', [rfReplaceAll]);
     HttpPos := Pos('http://', URL);
     if HttpPos > 0 then
       Delete(Url, HttpPos, 7);
     Result := URL;
     if eaLeaveOnlyURL in Actions then
     begin
       Result := Copy(Url, 1, Pos('/', Url) - 1);
       if Result = '' then
         Result := URL;
     end;
     if eaTrimLastSlash in Actions then
     begin
       Len := Length(Result);
       while Result[Len] = '\' do
       begin
         Dec(Len);
         SetLength(Result, Len);
         if Len = 0 then Exit;
       end;
     end;
    end;

    function FillSoapData(Value: IXMLNode): TSoapData;
    var
     I: Integer;
     Done: Boolean;
    begin
     Done := False;
     Result := TSoapData.Create;
     try
       for I := 0 to Value.AttributeNodes.Count - 1 do
         Result.Add(Value.AttributeNodes[I].NodeName, Value.AttributeNodes[I].NodeValue);
       Done := True;
     finally
       if not Done then
         FreeAndNil(Result);
     end;
    end;

    function FillWebSoapData(Value: IXMLNode): TSoapData;
    begin
     Result := FillSoapData(Value);
     if Result <> nil then
       Result.Add('_Url', Result.Items['Url']);
    end;

    function FillLibSoapData(Value: IXMLNode; const Path: string): TSoapData;
    begin
     Result := FillSoapData(Value);
     if Result <> nil then
       Result.Add('_Url', Path);
    end;

    function TFWSharePoint.GetLibraryList(const SharePointSrvAddr: string): TSoapDataList;
    var
     RealPath: string;
     RIO: THTTPRIO;
     Soap: ListsSoap;
     XMLData: TXMLData;
     I: Integer;
     Data: TSoapData;
     s: TStringList;
    begin
     Result := nil;
     RIO := GetRIO;
     try
       RealPath := ExtractURL(SharePointSrvAddr, [eaTrimLastSlash]);
       RealPath := GetUrlString(RealPath, atLists);
       Soap := GetListsSoap(False, RealPath, RIO);
       if Soap = nil then Exit;
       XMLData := Soap.GetListCollection;
       try
         if XMLData.XMLNode.ChildNodes.Count = 0 then Exit;
         Result := TSoapDataList.Create;
         for I := 0 to XMLData.XMLNode.ChildNodes.Count - 1 do
         begin
           Data := FillLibSoapData(XMLData.XMLNode.ChildNodes[I], SharePointSrvAddr);
           if Data <> nil then
             Result.Add(Data);
         end;
       finally
         XMLData.Free;
       end;
     finally
       if Soap = nil then
         RIO.Free;
     end;
    end;

    function TFWSharePoint.GetRIO: THTTPRIO;
    begin
     Result := THTTPRIO.Create(nil);
     Result.HTTPWebNode.UserName := UserName;
     Result.HTTPWebNode.Password := Password;
    end;

    function TFWSharePoint.GetUrlString(const Path: string;
     APIType: TSharePointAPIType): string;
    begin
     Result := Format(APITypeStrings[APIType], [Path]);
    end;

    function TFWSharePoint.GetWebSiteList: TSoapDataList;
    var
     RIO: THTTPRIO;
     Soap: WebsSoap;
     XMLData: TXMLData;
     I: Integer;
     Data: TSoapData;
     RealPath: string;
    begin
     Result := nil;
     RIO := GetRIO;
     try
       RealPath := GetUrlString(SharePointURL, atWebs);
       Soap := GetWebsSoap(False, RealPath, RIO);
       if Soap = nil then Exit;
       Result := TSoapDataList.Create;
       Data := TSoapData.Create;
       Data.Add('Title', 'SharePoint сервер');
       Data.Add('Url', HTTPPrefix + SharePointURL);
       Data.Add('_Url', HTTPPrefix + SharePointURL);
       Result.Add(Data);
       XMLData := Soap.GetWebCollection;
       try
         if XMLData.XMLNode.ChildNodes.Count = 0 then Exit;
         for I := 0 to XMLData.XMLNode.ChildNodes.Count - 1 do
         begin
           Data := FillWebSoapData(XMLData.XMLNode.ChildNodes[I]);
           if Data <> nil then
             Result.Add(Data);
         end;
       finally
         XMLData.Free;
       end;
     finally
       if Soap = nil then
         RIO.Free;
     end;
    end;

    procedure TFWSharePoint.SetUrl(const Value: string);
    begin
     FUrl := ExtractURL(Value, [eaLeaveOnlyURL, eaTrimLastSlash]);
    end;

  • Cobalt © (05.05.12 16:30) [3]
    Отладка на этапе конкатенации строк спасет ОРД :)
  • Rouse_ © (05.05.12 16:32) [4]

    > Cobalt ©   (05.05.12 16:30) [3]
    >
    > Отладка на этапе конкатенации строк спасет ОРД :)

    Шутку понял, по делу есть что?
  • Rouse_ © (05.05.12 16:45) [5]
    Собственно эту-же проблему описали и в каметах к MSDN документации: http://msdn.microsoft.com/en-us/library/lists.lists.getlistcollection%28v=office.12%29.aspx#2

    This method only returns back the 'ListCollection' of the Root Site within a site collection.

    только куда дальше копать не понятно...
  • WondeRu_ (05.05.12 18:44) [6]
    Приветствую!

    1. Советую глянуть в сторону Client Object Model http://msdn.microsoft.com/en-us/library/ee537247.aspx. Правда это счастье .NET. К сожалению, не помню, объявлены ли эти сборки как COM (старый добрый). Но ничего не мешает сделать COM-обертку.
    2. У шарика вполне вменяемые REST-сервисы. Покопайте
    3. Также есть магический WebDAV. Через него очень легко работать со стандартными библиотеками Шарика. Правда назначать права через WebDAV - та еще лебединая песня.
  • Rouse_ © (05.05.12 18:47) [7]
    Сеньк - покопаю в этом направлении.
    WebDAV пока не трогаю, он у нас под отдельную задачу запланирован и будет реализован чуть позже...
 
Конференция "Сети" » Получение списков SharePoint с дочерних сайтов
Есть новые Нет новых   [134435   +13][b:0][p:0.003]