요즘 한국 MS에서 SharePoint를 하나라도 더 많은 곳에 팔기 위해 많은 시도들을 하고 있다. 그래서 이 SharePoint를 많은 업체들에게 소개하고 영업을 하고 있다. 그 소개와 영업하기 위해 이 SharePoint의 많은 특/장점을 제시하는데,그 중 하나가 다국어 지원이다.

우리나라의 대부분 업체들이 말하고 있는 다국어 사이트라는 개념과 SharePoint와 외국인의 입장에서 보는 다국어 사이트라는 개념에는 상당한 차이가 있다.
특히 인트라넷 시스템을 기준으로 볼 때, 확연하게 틀리다.

우리나라의 대부분의 업체들이 말하는 다국어 시스템이라는 것은, 사이트내에 담긴 내용과는 별개로 각종 메뉴나 외부 틀에 보이는 모든 형태가 언어별로 다르게 표시되는 시스템을 원한다. 즉 게시판을 예를 들면 게시판의 내용은 한국어가 되었던 영어가 되었던, 러시아어가 되었던 외부의 틀만은 언어 중립적으로 표시되어야 한다는 것이다. ( 유니코드가 나오기 전에는 어떻게 되었는지 궁금할 따름이다. )

외국 입장(SharePoint와 외국인들)에서는 사이트의 내용에 따라 틀도 달라진다는 의미로 해석하면 된다. 만일 영어 사이트라면 틀도, 내용도 영어로만 적혀 있어야 한다. 한국어 사이트면 틀도, 내용도 모두 한국어로 나와야 된다는 의미이다. 즉 언어별로 별개의 사이트로 구성되서 진행되는 것이다.

다국어에 대한  이 차이점은 고객과 SharePoint를 적용하는데 있어 큰 걸림돌이 되고도 남는 부분이 된다. 그냥 다국어라고 MS에서는 이야기 하기 때문에, 고객입장에서는 당연히 언어 설정을 하면 그에 맞게 모든 사이트의 형태가 휘리릭 바뀌기리라 생각하고, SharePoint에서는 다른 언어인 경우 별도 사이트를 구축하여 제공하는 것이다.

어느 쪽 생각이 옳은지는 전혀 모르겠지만, 최소한 국내 IT 업계에서 일하는 만큼 전자를 따르는 것이 옳을지 모르겠다.
하지만, 이런 국내 고객들의 입맛에 맞게 SharePoint로 다국어 지원 사이트를 만든다는건, SharePoint의 기본 기능은 안 쓰고 대거 손을 대버리겠다는 의미와 동일하다.( 결국, 개발자만 죽어나거나, 안하니만 못한 시스템이 구축된다. )

과연 이 사실을 몇몇이나 알지 모르겠다.
728x90

보통 일반적인 게시판에서는 올린 글에 대해서는 누구든지 보게 된다.
또한 특정 글의 수정 작업은 자신이 작성한 항목에 대해서만 수행할 수 있게 된다.

그런데, 혹시 아래와 같은 기능이 필요할 수 있다.
1. 하나의 게시판을 여러사람이서 공유하지만, 마치 자신만의 글만 보이도록 하고 싶다.
2. 어떠한 글이든, 권한만 있으면 편집이 가능하다.
3. 모든 사용자가 아이템 자체를 편집 못하게 한다. ( 마감 처리 )

사실 1번과 같은 사항은 대개 View를 수정해서 자신이 작성한 글만 보이게 처리할 수 있다.
하지만, 만일 View를 바꿔 보게 되면 전체가 다 보이므로 1번의 조건에 합당하게 처리되지 않는다.  2번 같은 경우에는 글이나 문서가 공유되는 것이라서 팀 사이트 의 경우 팀 구성원이 원하는데로 수정가능한 경우를 의미한다.
3번의 경우는 해당 게시판의 만료적인 의미로 두면 되며, 더 이상 누구도

이 처리를 위한 방법은 SPList의 속성 중 아래의 2개의 프로퍼티가 이런 기능을 제공하게 된다.

int SPList.ReadSecurity

 속성 내에 넣는 값
 1 - 모든 사용자가 모든 아이템을 읽을 수 있다.
 2 - 자신이 생성한 아이템에 대해서만 읽을 수 있다.

int SPList.WriteSecurity

 속성 내에 넣는 값
 1 - 모든 사용자가 모든 아이템을 권한만 있으면 편집 가능하다.
 2 - 사용자가 생성한 아이템만 편집 가능하다.
 4 - 누구도 아이템에 대해 편집이 불가능하다. ( 사이트 관리자만 가능 )


위의 속성만 세팅하게 되면, 각각의 기능을 수행할 수 있게 된다.

기본 값으로 ReadSecuriry는 1이, WriteSecuriy는 1로 설정되어 있다.

만일 위의 3가지 요구사항중 1번을 처리하려면,
ReadSecurity를 1, WriteSecurty는 1또는 3을 넣으면 된다.

2번을 처리하려면,
ReadSecurity를 1, WriteSecurty는 1로 넣으면 된다.

3번을 처리하려면,
ReadSecurty를 1, WriteSecurty를 4로 넣으면 된다.

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

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

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

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

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

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

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



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


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

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




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




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


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

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


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


728x90

SPList 개체에서 특정 사용자의 특정 권한을 체크하고 싶을 때 사용하는 방법이다.
일전 SK 에너지(구 SK Corp)에서 게시판에서 처리한 방법을 보면
아래와 같이 처리되어 있었다.

// 1번 그룹이 바로 글 쓰기 권한
SPList list = SPContext.Current.Web.GetList(".....");
newItemGroup = 1;
usableNewItem = false;
SPGroup group = SPContext.Current.Web.Groups[newItemGroup];
if( group.ContainsCurrentUser == true )
{
      // SPList에 글쓰기가 있으니.. 쓰는 권한에 관련된 처리를 여기에..
      SPListItem newItem = list.items.Add();
       ......
}


위의 방법대로 하기 위해서는 newItemGroup의 그룹을 찾아야 되는 문제가 있다.
이에 간단하게 해결하는 방법이 있는데 아래와 같다.

SPList list = SPContext.Current.Web.GetList(".....");
if(list.DoesUserHavePermissions(SPBasePermissions.AddListItems))
{
     // SPList에 글쓰기가 있으니.. 쓰는 권한에 관련된 처리를 여기에..
      SPListItem newItem = list.items.Add();
       ......
}

DoesUserHavePermissions 이 메소드 안에, SPBasePermissions 항목에
체크하고자 하는 권한들을 넣으면 된다.
만일 여러개의 권한 체크가 필요할 시에는 '&'로 연결해서 체크하면 된다.

if(list.DoesUserHavePermissions(SPBasePermissions.AddListItems | SPBasePermissions.EditListItems))
{
    // SPList에 글쓰기가 있으니.. 쓰는 권한에 관련된 처리를 여기에..
      SPListItem newItem = list.items.Add();
       ......
}



수정 : if(list.DoesUserHavePermissions(SPBasePermissions.AddListItems & SPBasePermissions.EditListItems)) 라고 썼던 부분을
if(list.DoesUserHavePermissions(SPBasePermissions.AddListItems | SPBasePermissions.EditListItems)) 로 수정합니다.
& -> |


 

728x90

List 템플릿 추가 중에 아래와 같은 오류가 끊임없이 발생하여,

추가 List 템플릿으로 web.Lists.Add(".....", "......", listTemplate) 메소드로 SPList를 추가할 수 없는 경우가 있습니다.

System.Data.SqlClient.SqlException:

테이블 'WSS_Content.dbo.EventReceivers', 'Name' NULL 값을 삽입할 수 없습니다. 열에는 NULL을 사용할 수 없습니다.

INSERT() 실패했습니다.  문이 종료되었습니다.    

 

위치: System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) 
위치: System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)

위치: System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler,
 SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
위치: System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async)
위치: System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result,
 String methodName, Boolean sendToPipe)    

위치: System.Data.SqlClient.SqlCommand.ExecuteNonQuery()    

위치: Microsoft.SharePoint.Utilities.SqlSession.ExecuteNonQuery(SqlCommand command)

 

이 내용을 확인해 본 결과 List Template 안의 Event Add 하는 부분에서 아래와 같은 부분을 확인 할 수 있었습니다.

List Template Element.xml 을 살펴본 결과 아래와 같습니다.

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <!-- 리스트 템플릿 정의부분 -->

  <ListTemplate

        Name="FreeTalk_Board"

        Type="8000"

        BaseType="0"

        OnQuickLaunch="TRUE"

        SecurityBits="12"

        Sequence="392"

        DisplayName="FreeTalk_Board"

        Description="FreeTalk_Board"

        Image="/_layouts/images/itann.gif"       

        />

  <!-- 이벤트 리시버 정의부분 -->

  <Receivers ListTemplateId="8000">

    <Receiver>

      <Name>CollectBoardEventReceivers</Name>

      <Type>ItemAdded</Type>

      <SequenceNumber>50000</SequenceNumber>

      <Assembly>SKT.TSquare.SPS.FreeTalk, Version=1.0.0.0, Culture=neutral, PublicKeyToken=388b774ba96c947e</Assembly>

      <Class>SKT.TSquare.SPS.FreeTalk.CollectBoardEventReceivers</Class>

      <Data />

      <Filter />

    </Receiver>

    <Receiver>

      <Name>CollectBoardEventReceivers</Name>

      <Type>ItemDeleting</Type>

      <SequenceNumber>50000</SequenceNumber>

      <Assembly>SKT.TSquare.SPS.FreeTalk, Version=1.0.0.0, Culture=neutral, PublicKeyToken=388b774ba96c947e</Assembly>

      <Class>SKT.TSquare.SPS.FreeTalk.CollectBoardEventReceivers</Class>

      <Data />

      <Filter />

    </Receiver>  

  </Receivers>

</Elements>

 

일단  <Receivers> .... </Receivers> 부분에 있는 내용을 모두 삭제해 보고 리스트를 추가해 본 결과,

위의 오류가 발생하지 않았습니다.

이번에 다시 추가해서 적용해 본 결과 오류가 재발하였습니다.

그래서 이번에는 각 Event의 이름을 다르게 적용해 보았습니다.

 

   ....

  <Receivers ListTemplateId="8000">

    <Receiver>

      <Name>FTEventItemAdded</Name>

      <Type>ItemAdded</Type>

      <SequenceNumber>50000</SequenceNumber>

      <Assembly>SKT.TSquare.SPS.FreeTalk, Version=1.0.0.0, Culture=neutral, PublicKeyToken=388b774ba96c947e</Assembly>

      <Class>SKT.TSquare.SPS.FreeTalk.CollectBoardEventReceivers</Class>

      <Data />

      <Filter />

    </Receiver>

    <Receiver>

      <Name>FTEventItemUpdated</Name>

      <Type>ItemDeleting</Type>

      <SequenceNumber>50000</SequenceNumber>

      <Assembly>SKT.TSquare.SPS.FreeTalk, Version=1.0.0.0, Culture=neutral, PublicKeyToken=388b774ba96c947e</Assembly>

      <Class>SKT.TSquare.SPS.FreeTalk.CollectBoardEventReceivers</Class>

      <Data />

      <Filter />

    </Receiver>  

  </Receivers>

   ....

 

확인해 본 결과 위와 같이 변경하니, 그 이상의 오류는 발생하지 않았습니다.

그 이후에는 이름이 동일해도 오류가 발생하지 않았습니다.

초기에 리스트 템플릿 상에서 동일한 이름으로 등록할 때 발생되는 오류로 생각됩니다.

728x90

+ Recent posts

728x90