대부분의 MOSS 2007 개발자들은 이 사이트와 웹 간의 차이를 명확히 모르거나 어렴풋이 알아도 그게 그거가 아닌가 라는 어조로 표현하곤 한다.
하지만 개념적으로 명확히 틀린 구조이며 그 차이는 명확히 틀리다.

다음 그림을 보면 대략적으로 왜 사이트와 웹이 틀린지 알 수 있다.



즉 사이트 여기서는 SPSite인데, 최상위의 일종의 거대한 상자라고 보면 될 것이다. 이 안에 무수한 SPWeb을 붙여서 하나의 사이트를 만드는 것이다. 즉 사용자들은 SPWeb을 보는 것이지 SPSite를 보는 것은 아니다. 실제 사용자가 보기 위한 페이지, 리스트들의 모든 정보들은 바로 저 SPWeb에서 나오고, 그 외에 전체 검색이나, 차이점 분석 결과 등 전체 사이트에 대한 설정, 구성, 정보들은 SPSite에서 다루게 된다.
우리가 보통 새끼까기 하듯이 사이트 아래에 사이트를 만든다고 하는데, 그건 SPSite를 만든 것이 아니고 바로 저 SPWeb을 만드는 작업이라고 보면 된다.

보통 개발자들이 혼돈을 느끼는 부분이 바로 여긴데, MOSS 관리자 페이지에 가면 사이트 만드는 부분의 명칭이 "사이트 모음 만들기" 라고 적혀 있고, 해당 사이트의 페이지에 가서 사이트 관리 도구에 들어가면 하위 사이트 만들기 라고 적혀 있으니, 사이트 모음 = SPSiteCollection, 사이트 = SPSite 라고 생각하는 우리의 입장에서는 이 또한 무슨 망발이냐!!! 라는 의문을 바로 제기할 수 있다. 

그.러.나. SDK를 보면 우리를 또 한번 더 햇갈리게 한다. 양키 말을 들어보면 Web, Site 구분없이 막지껄이고 떠든다. 뭐가 Web이냐, Site냐.. 최소한 난 이것 때문에 상당한 혼란을 일으켰다. 그러면 저 SPSite와 SPWeb은 1:1로 하나씩 묶여서 구성된 건가... 했다.

그러나 진실은 SPSite는 무조건 한개, 그 하위의 모든 사이트들은 SPWeb이다. 그를 증명하는 부분은 바로 컨텐츠 DB. 만일 사이트 모음을 한개 만들어 놓고, 그 안에 새끼 까듯이 계속 사이트들을 만들어 99개를 만들었다고 하자. 그 때 컨텐츠 DB안에 사이트는 몇개 일까?
    1개다.
궁금하신 분은 테스트 해보시면 알 수 있다.
즉 사이트 모음은 SPSite를 의미하기 때문에, 그 SPSite 갯수인 1개가 들어가고 그 이후에는 어차피 SPSite 내에 포함된 하위 SPWeb들이기 때문에, 컨텐츠 DB 입장에서는 사이트 갯수에 포함 안되고, 단지 1개의 SPSite가 좀 커졌구나... 정도로 인식할 뿐이다.
(즉 늘어나는건 컨텐츠 DB의 사이즈 뿐이다.)

이런 개체들의 관계를 따라, 각 개체를 참조 할 때는 아래와 같이 찾아 들어가면 된다.

Microsoft.SharePoint.Administrator.SPWebApplication 로 가는 방법

  [SPSite 개체].WebApplication


Microsoft.SharePoint.SPWeb로 가는 방법

  [SPSite 개체].OpenWeb("url")


그리고 만일 위의 그림에서 1번 사이트를 연 뒤 (new SPSite("1번 사이트 URL")) 한 뒤, 저 OpenWeb을 써서 2번 사이트 아래의 웹을 찾으려면 당연하게 오류를 뿜는다. 저렇게 그림으로 보면 당연하거 아녀? 라고 되묻겠지만, 간혹 어떤 분들이 1번 사이트 열어놓고, 2번 사이트 내의 웹이 안 열린다고 투덜 댄다. MOSS 2007 버그니 뭐니.. 하는데... 한번 즈음 소스 검사 해보심이 ...


그리고 만일 특정 SPSite 및의 모든 하위 사이트(절대 SPSite가 아니다, SPWeb 이다.)에 대해 세팅을 동일하게 적용한다고 했을 때는 해당 SPSite를 열고 RootWeb을 연 뒤, 그 RootWeb에서 Webs를 이용하여 트리 탐색하듯이 찾아 들어가야 한다. 1번 사이트를 보면 그 아래의 SPWeb 아래 SPWeb들을 뒤져야 된다.
그 검색로직은 트리를 찾는 방법대로 진행되어야 할 것이다.

728x90

기본 제공하는 Field 중 User 필드가 있다.  이 안의 값을 가져오면 다음과 같은 형식으로 저장되어 있다.

WebID#;사용자이름.


만일 해당 SPWeb 내에 Users 내에 강냥이 라는 사용자가 등록되어 있을때,

44#;강냥이

이런 식으로 기록된다. 물론 저 44라는 것은 SPUser의 ID를 의미한다. ( 무슨 숫자가 될지는 SPWeb 이 알아서 결정한다. )
예전에 이 필드 내에 있는 값을 참조할 때는 #;를 구분자로 나누어 44로 SPUser를 찾아 값을 처리하고 그 뒤의 문자열로 값을 처리했다. 언제나 저 문자열에 대해 SPlit 로 해서 배열 짜서, 하나씩 대응 했다.

이 작업이 쉽다고 하면 쉬울 수 있겠지만, 은근히 짜증나는 작업이 아닐 수 없다. 그렇다고, 이 작업을 위한 별도의 Static 함수 만들기도 애매모호 할 때 가 있다. ( Utility 함수들이 담긴 별도의 DLL을 만든다고 할 때, 그 DLL을 모든 프로젝트에 포함시켜줘야 할 것이다.)

이 때 해결해주는 구세주가 있으니 바로 SPFieldUserValue 라는 클래스 이다.
이 클래스를 사용하면 모두 끝난다고 보면 된다.
사용방법은 간단하다.

SPList list = web.GetList(http://wataru/Lists/Test);
SPListItem item = list.Items[0];
string sAuthorContext = item["Author"] as string;
SPFieldUserValue authorValue = new SPFieldUserValue(list.ParentWeb, sAuthorContext);
if(authorValue.User != null)
{
    String sLoginName = authorValue.User.LoginName;
}
else
{
      // 웹 내에 사용자가 없음
}


즉 SPFieldUserValue 클래스를 new로 생성할 때, 해당 SPWeb 개체와 User 필드내의 값 String만 넣으면 그 결과값을 바로 확인 할 수 있다.

.......

이 내용은 http://www.sharepoint-tips.com/2007/10/another-simple-code-snippet-using-user.html 에서 본 뒤 쇼크 받고 올린다.

728x90

Document Library는  SPList의 한 종류인 동시에, 오로지 File만을 저장할 수 있는 일종의 웹폴더와 같은 구조로 된 변종 List 이다.
SPList로써 생성을 할 때, List Template 중 “문서 라이브러리”라는 형태로 만들어 주면 탄생하게 된다.그러나, 일반 Customize List 처럼 다양한 Field들을 엮는 형태가 아니고, 기묘하게 그 안에 폴더를 넣을 수 있으며 다양한 종류의 파일을 독자적으로 넣을 수 있게 되어 있다.

그러기에 지금까지 게시판 류와 같은 형태로 다루기에는 조금 내용이 다르게 진행 된다.
이 작업 중 가장 나에게 큰 태클을 걸어주신 부분은 바로 Folder 만들기.
이 부분을 하기 위해 SPList의 각종 메소드들과 속성들을 확인해 봤는데, 가장 근접한 내용은 바로 Folders라는 항목을 이용하는 것까지는 알았는데, Add를 해도 Item을 업데이트 해도 반응이 없었다. 게다가, Add 안에 들어가는 Url의 의미도 정확히 알 수도 없었다.

이에 몇 개 사이트를 돌아다니다가, 겨우 방법을 찾았다.

만일 아래와 같은 구조의 문서 라이브러리 가 있다고 할 때 생성 방법은 아래와 같다.

// 문서라이브러리1 ---> AAAA -> BBBB
//                      |
//                       --> AAAA2


// 문서 라이브러리에 해당하는 List를 얻어온다.
SPList docLib1 = web.Lists[“문서라이브러리1”];

// 문서 라이브러리의 옵션 중 폴더 생성 가능하도록 한다.
docLib1.EnableFolderCreation = true;

// AAAAA 폴더를 생성한다.
SPFolder fld_AAAAA = docLib1.RootFolder.SubFolders.Add(docLib1.RootFolder.Url + “/” + “AAAAA”);
fld_AAAAA.Update();

// AAAAA 밑의 BBBB를 생성한다.
SPFolder fld_BBBB = fld_AAAAA.SubFolders.Add(fld_AAAAA.Url + “/” + “BBBB”);
fld_BBBB.Update();

// AAAAA와 동일한 레벨로 AAAA2를 생성한다.
SPFolder fld_AAAA2 = docLib1.RootFolder.SubFolders.Add(docLib1.RootFolder.Url + “/” + “AAAA2”);
fld_AAAA2.Update(); 


즉 리스트의 RootFolder라는 부분에서 시작하여 SubFolder라는 속성값을 이용해 계속 Add로 추가해 준다. 해당하는 Url은 리스트의 RootFolder URL을 시작으로해서 계속 내려가 주면 된다. 무엇보다 제일 먼저 SPList의 EnableFolderCreation을 반드시 true로 만들어 준다.

728x90

MOSS 2007 을 설치한 후, 예전에 CPU 개수(또는 코어) 만큼 웹가든을 만드는 것이 좋다는
의견이 있었다. 그런데, 이 내용은 32bit에서나 적용될 내용이라는 것이다.
그 이유는 보통 32Bit에서는 내부 가상 메모리의 최대 크기가 2G 뿐인데,
만일 700M 이상 넘어가면, 가비지 Collection 작업이 돌게 되는데,
이 때 CPU 사용률이 엄청나진다는 것이다. 그래서 가급적 32Bit 머신에서는
여러개의 웹가든을 두어 이 가비지 Collection 작업을 적게 발생하도록 하는 것이다.

그런데, 64Bit 에서는 최대 가상 메모리 크기가 7T 이기 때문에,
이 가비지 Collection 작업이 전무 하다. 그러므로 여러개의 웹 가든을 잡을 필요조차 없다.
이 사항은 MS SharePoint 프로덕트 팀에서 말한 내용에서 언급 되어 있다.
( MOSS 2007 SP1 배포 문서에 이 내용이 담겨 있다고 한다. )

728x90

People Picker 라는 것은 SharePoint 내에 특정 사용자나 그룹 등을 등록할 때 사용하는 UI용 웹컨트롤을 의미한다. SharePoint를 사용하다 보면, 사용자 등록 할 때 보이는 부분(아래 그림 참조)가 있는데 그 것이 바로 People Picker 이다.




이 기능은 설치된 SharePoint의 기본 인증 형태에 따라 사용자 검색하는 방법이 알아서 적절히 바뀌어 적용된다. 로그인 이름이로도 되고, 한글 이름도 되고, 이메일도 가능하다.
물론 사용자 프로필을 어떻게 엮어 놓았냐에 따라 잘 될 수도 안될 수도 있다.
일단, AD를 이용하여 구성했다면, 큰 문제  없이 이용할 수 있다.
아래의 설명도 최소한 AD로 구성된 시스템에서는 문제 없이 사용할 수 있을 것이다.
그리고 설명을 위해 ASPX 페이지 구성을 기준으로 설명할 것이다.

1. Web Control 붙이기.
이 웹컨트롤을 붙이기 위해서는 ASPX 페이지 소스 상에 WSS에 대한 Name Space를 정의해 준다.

<%@ Register Tagprefix="wssawc" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%@ Register ..... %>라는 지시어를 이용해서 Microsoft.SharePoint.Webcontrols를 정의해준다. 여기서는 wssawc 라는 이름으로 구성한다.

2. 붙이고 싶은 위치에 웹컨트롤 붙이기.
Table이 되었던, 날 페이지위에 되었던 간에 원하는 위치에 아래와 같은 형식으로 Web Control 코드 부분을 붙인다.
<wssawc:PeopleEditor
        AllowEmpty=false
        ValidatorEnabled="true"
        id="userPicker"
        runat="server"
        ShowCreateButtonInActiveDirectoryAccountCreationMode=true
        SelectionSet="User,SecGroup,SPGroup"
        />

일단 각 옵션들에 대한 자세한 설명이나 추가 옵션에 대해서는 WSS 도움말(WSS SDK)에서 PeopleEditor를 참조한다.

3. PeoplePicker에서 선택한 내용 읽어 오기.
1~2 까지 해서 ASPX 페이지를 구성한 뒤 띄워보면, 맨 위의 그림과 같은 PeoplePicker를 볼 수 있다. 그 안에서 사람이름을 치거나, 로그인 이름을 치고 사람 아이콘에 체크 모양이 있는 버튼을 클릭하면,  자동으로 이름으로 변경되면서 밑줄이 그어짐을 볼 수 있다.



이렇게 입력한 내용을 읽어오는 부분을 소스로 구성하면 아래와 같다.

ArrayList aryAccounts = userPicker.Accounts;
if (aryAccounts.Count == 0)
      return string.Empty;
StringBuilder sb = new StringBuilder();
foreach (string sKey in aryAccounts)
{
      sb.Append(sKey);
      sb.Append(";");
}
return sb.ToString();

위의 소스 중 핵심적인 부분은 바로 굵은 줄 부분인데, Picker 컨트롤의 Member 중 Account를 열면 ArrayList가 나오게 된다. 일단 이 ArrayList를 꺼내서 보게 되면, 문자열로 로그인 이름이 나오게 되는데, 그 로그인 이름을 이용하여 원하는 조작을 수행하면 된다.
위의 소스에서는 Picker로 선택한 사용자의 모든 로그인 이름을 ";"으로 구분하여 하나의 문자열로 만드는 것이다.

4. PeoplePicker에 특정 데이터 넣기.
이번에서는 소스에서 PeoplePicker 내에 특정 값을 넣는 작업이다. 처음에는 추가하고자 하는 값을 넣는 메소드나 콜랙션 프로퍼티가 없어서 난감했다. 더욱이 위의 Accounts 라는 콜랙션에 직접적으로 ADD 할 수 없었다. 이에 Method를 더 확인해 본 결과, ArrayList를 통채로 넣는 UpdateEntities 라는 함수를 이용해야 했다.
그런데, 이 ArrayList 라는게 값을 넣는 방법이 Object 라서 로그인 이름을 그냥 넣어서 추가했더니 이번에는 단순 문자열은 받아 줄 수 없다는 오류가 발생하면서 넣어지지 않는 것이다. 그래서 이래저래 짱구를 굴린 결과 아래와 같은 형태의 소스를 구성할 수 있었다.
ArrayList aryAccounts = userPicker.Accounts;
aryAccounts.Clear();
if (string.IsNullOrEmpty(sAdminList) == false)
{
    string[] aryAdminList = sAdminList.Split(';');
    foreach (string sAdminID in aryAdminList)
    {
        Microsoft.SharePoint.WebControls.PickerEntity newEntity = new Microsoft.SharePoint.WebControls.PickerEntity();
        newEntity.Key = sAdminID;
        newEntity = userPicker.ValidateEntity(newEntity);
        aryAccounts.Add(newEntity);
    }
}
userPicker.UpdateEntities(aryAccounts);

핵심적인 부분은 저 굵은 글자가 된 부분이다.
일단 Accounts를 이용해서 ArrayList를 가져온다.
그리고 난뒤 PickerEntity 라는 클래스를 이용해 새로운 PickerEntity를 만든다.
이 새로 만든 PickerEntity의 속성 값에 로그인 이름이나, 이메일 등 검색 단서에 해당하는 값을 넣어준다. 여기서는 제일 만만한 로그인 이름을 넣었다.
그리고 난뒤, PeoplePicker를 이용해서 ValidateEntity 함수를 실행해준다. 이렇게 실행하면 PeopleEntity가 새롭게 돌려주는데, 이 안에 Key 값외의 다양한 속성 값들을 채워 준다.
이 새롭게 채운 PeopleEntity를 ArrayList에 추가한다.
그리고 난 뒤 업데이트 된 ArrayList를 UpdateEntities라는 메소드를 이용해 추가해 준다.

--- 이미지업데이트 : 고객사 사이트에서 자료를 캡쳐해 오다가 보니, 실수로 고객사 분 성함과 이메일이 그대로 노출되 버렸더군요... 다행히 회사의 김진 과장님이 가르쳐 주셔서 잽싸게 모자이크 처리를....-_-;;; 이런 실수 안해야 되는데, 큰일 날뻔 했습니다.


728x90

Site administrator를 등록하려면, 보통 사이트 설정에 들어가 사이트 관리자 설정에 들어가,

추가하면 된다.

 

그러나 프로그래밍 상으로 추가하려면, 단순히 Site Users와 같은 컬랙션에 추가해서 되지 않는다.

실제로 SPWeb 내에 SiteAdministrators 라는 SPUserCollection이 있기는 하지만, 이 컬렉션은

Get 용이며, 여기에 Add 해봐야 아무런 반응을 보이지 않는다.

 

방법은 해당하는 사이트에 등록된 사용자의 SPUser 개체를 가져와, SPUser에서 제공하는 IsSiteAdmin true로 만들어주면 된다.

 

예제 소스는 아래와 같다.

 

///   
/// 모든 관리자를 해당 Site에 추가  
///   
///   
///   
///   
static void AddSiteAdmins(SPSite site, SPWeb web)  
{             
    // 관리자 목록에서 사용자 등록  
    foreach (string sAdminLoginName in TeamCommMemberSync.arySiteAdminList)  
    {  
        SPPrincipalInfo info = SPUtility.ResolveWindowsPrincipal(site.WebApplication, sAdminLoginName, Microsoft.SharePoint.Utilities.SPPrincipalType.User, false);  
        // 인증정보를 성공적으로 가져오면 처리  
        if (info != null)  
        {  
            // 해당 사용자를 group내에 있는지 확인  
            SPUser user = null;  
            try  
            {  
                user = web.SiteUsers[info.LoginName];  
            }  
            catch  
            {  
                user = null;  
            }  
                    
            // 해당 group내에 해당 사용자가 없으면, 추가 처리.  
            if (user == null)  
            {  
                try  
                {  
                    // 해당 사이트에 추가  
                    web.SiteUsers.Add(info.LoginName, info.Email, info.DisplayName, info.DisplayName);  
                    web.Update();                         
                    user = web.SiteUsers[info.LoginName];                                 
                }  
                catch  
                {  
                    //Utils.AppLogger.ExceptionLogWrite(this.GetType(), ex);  
                }  
            }  
            if (user != null)  
            {  
                user.IsSiteAdmin = true;  
                user.Update();  
            }  
        }  
    }  
}
 

핵심 부분은 45라인 부분이다.
해당하는 SPWeb 개체에서 얻은 SPUser 개체에 값을 설정하고 Update 해주면 완료된다.

만일 위의 작업이 실패하는 경우의 케이스로는 해당하는 SPWeb 개체를 가져올 때, Site Administrator외의 일반 계정으로 SPWeb을 열었을때는

에러가 발생하게 된다.

 

현재까지 테스트된 사항에 의거하면, 최소한 저 위의 코드가 실행하는 주체가 Site Administrator 일 경우에는 문제없이 실행된다.

728x90

Windows Live Writer가 역시 MS에서 제작된 기능이기에,
보다 쉽게 SharePoint 내에 있는 블로그에 접근 가능하다.
사실 SharePoint의 웹 상에서 블로그 글을 작성하는 기능은 생각보다 한계가 많은 편이다.
보안적인 문제로 인해 더 이상 Active X 기반의 웹 에디터를 기본 제공하지 않기 때문에,
완전 웹 기반의 도구다 보니, 표기능도 부실하고, 이미지 넣는 기능도 부실하며,
기타 글 작성하는데도 비좁고 기록도 바로 바로 하기 힘들다.

이에 반해 Live Writer는 태생 자체가 MS Word나 FrontPage와 같기 때문에,
넓은 화면에 다양한 기능들이 들어가 있기에 편하게 작업할 수 있다.
만일 기록할 생각이 있다면,아래와 같이 수행하면 된다.

  1. Live Writer를 다운 로드 받아 설치한다. ( 단 Windows XP, Vista만 지원 )
  2. 초기 계정 설정 화면에서 SharePoint 웹로그를 선택한다.
  3. 다음 버튼을 클릭하면 해당 웹 로그 주소를 넣으라고 하는데, 블로그 메인 페이지 주소를 넣어주면 된다.
    ( 이 블로그 주소는 http://intranet.neosystem.net/personal/neohind/Blog/default.aspx 이기에 이 주소를 넣었음)
  4. 자동으로 무언가 설치가 진행된다.
    (중간에 스타일 같은 것을 묻는 창이 뜬다면 이 블로그는 커스터마이징이 된것이기 때문에, 추가적인 설정이 필요하다.
    자세한 사항은 해당 블로그 설정이나 다른 관련 정보를 참고해야 할 것 같다.)  

지금 이 글도 Writer를 이용해서 포스트 작성 중인데, 생각보다 좋은 기능인듯 싶다.
이 쪽 TextCube 쪽의 블로그는 위의 SharePoint 블로그와는 다르게 직접적인 설정이 추가적으로 필요하긴 하지만,
직접 웹을 핸들링 하는 것보다는 편리하게 글을 작성할 수 있다는 잇점이 있는 것같다.

당분간은 이 블로그에서도 Windows Live Writer를 활용하려 한다.

728x90

권한이 없는 사이트에 접속 시, 보통은 액세스 거부 창이 뜹니다.

이 때 다른 사용자로 로그인 외에 “액세스 요청”이라는 항목이 더 생길 수 있는데,

일반적인 형태로 생성하는 경우 “액세스 요청” 이라는 항목이 생기지 않습니다.



이 경우 해당 사이트 설정에서 바꿔주거나 프로그램 상에서 변경 가능합니다.


1. 사이트 설정 변경하기
사이트 설정에 들어가서 “사용자 및 사용 권한” -> “고급 사용 권한”에 들어갑니다.

그리고 고급 사용 권한 리스트가 뜨면 설정을 클릭해서 액세스 요청에 들어갑니다.




그리고 난 뒤, “액세스 요청 허용”을 체크해주시고, 액세스 요청에 대한 이메일을 어디로 보낼지, 메일 주소를 넣으면 됩니다.




2. 프로그램 상으로 변경하기.
원하는 사이트의 SPWeb을 엽니다.(SPWeb 가져오는 방법에 대해서는 별도로...)
그리고 난 뒤, SPWeb 이 web 이라는 변수로 되었다고 했을때,


web.RequestAccessEmail
안에 원하는 Email 주소를 넣어주기만 하면,

자동으로 액세스 요청 항목이 활성화 됩니다.


만일 허용하지 않으려면, string.Empty 혹은 null을 넣으시면 됩니다


728x90

+ Recent posts

728x90