예전 2007 시절에는 asmx 파일을 적당히 올려서 웹서비스를 구축했다. 특히 javascript를 이용해서 데이터를 전달할 때는 aspx 파일로 적당히 만들어 JSON으로 Return 하는 식으로 만들곤 했다. 그런데, 이번에 SharePoint 2010으로 넘어오면서 기존에 Copy&Paste 식의 배포가 아닌 SharePoint 솔루션 방식으로 하다 보니, 위의 방식으로 하기에는 왠지 폼이 나지 않았다. 게다가 WCF 라는 나름 유연한 통신 방식을 활용하고 싶다는 생각도 들었다.

그래서 WCF 인터페이스를 어떻게 WSP로 싸서 업로드 하고 그 내용을 Client를 통해 제어를 하는지 살펴보려고 한다.

이 모든 작업은 SharePoint 2010 을 기준으로 하며, 개발 도구는 Visual Studio 2010 으로 한다.

 

1. SharePoint Project 만들기.

새 SharePoint Project를 만든다. 템플릿 트리에서는 Visual C# –> SharePoint –> 2010 을 선택하고, 목록에서는 Empty SharePoint Project 를 선택한다. 적당한 위치에 프로젝트 이름과 위치를 결정하고 생성한다.

그리고 난 뒤, 배포 위치를 설정한다.
URL이 있는데, 이 URL은 디버그를 하기 위한 URL이다. 가급적 로컬로 잡는 것이 작업하는데 편하다. 굳이 이 부분의 URL에 연연하지 않아도 된다. 그리고 그 밑에 솔루션 유형을 선택하는 부분이 있는데, 그 중 “Deploy as a farm solution”을 선택한다.

 

WCF를 설치하는 작업은 _vti_bin 과 같은 시스템 쪽 위치의 가상 디렉터리를 활용할 예정이기 때문에, 제한된 형태로 구성되는 Sandboxed solution 으로는 무리가 있다. 그러므로 farm solution 으로 선택한다.

다 구성되면 다음과 같은 솔루션 구성을 보여준다.

 

2. WCF 파일 구성.

먼저 WCF 파일을 담을 위치를 구성한다. 구성하는 방법은 배포용 폴더 위치를 추가해주면 된다. 웹 서비스나, WCF와 같은 외부 노출된 실행 모듈은 대부분 /_vti_bin 에 위치해 있다. 이 폴더는 SharePoint 설정 및 도구가 있는 14 폴더 중 ISAPI 이다. ( 예 C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI )

배포 도구에서 해당 위치에 파일을 하기 위해서는 해당 배포 위치를 구성해줘야 하는데, 배포 폴더를 하나 추가해줘야 한다. 추가하려면, 프로젝트 위에서 오른쪽 클릭을 해서 Context Menu를 띄운다. 그리고, Add –> SharePoint Mapped Folder... 를 선택한다.

SharePoint Mapped Folder를 클릭하면, Add SharePoint Mapped Folder 창이 뜨면, 그 중에 ISAPI를 선택한다.

이제 WCF용 파일들을 만들어야 된다. 이 파일들을 직접 cs 파일들과 svc 파일을 만들어도 되지만, WCF 프로젝트를 잠시 추가해서 템플릿을 받아 사용하는 것이 좋다.

솔루션에서 새로운 프로젝트를 추가하고, 프로젝트 중에서 WCF Service Library를 선택한다.
 

템플릿을 통해 만들어진 다음 2개의 파일을 SharePoint의 프로젝트에 복사한다.

  • Service1.cs
  • IService.cs

적당한 폴더를 만들어 구성할 수도 있고, 아니면 프로젝트 루트에 복사할 수도 있다.

이 파일은 WCF를 구성하기 위한 구성요소들로 IService.cs는 Contract를 담당하는 Interface 파일과 다른 하나는 그 Contract를 구현하는 구현 코드가 담기는 파일이다. 그 내용은 다음과 같다.

IService1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfServiceLibrary1
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string GetData(int value);

        [OperationContract]
        CompositeType GetDataUsingDataContract(CompositeType composite);

         // TODO: Add your service operations here
    }

    // Use a data contract as illustrated in the sample below to add composite types to service operations
    [DataContract]
    public class CompositeType
    {
        bool boolValue = true;
        string stringValue = "Hello ";

        [DataMember]
        public bool BoolValue
        {
             get { return boolValue; }
             set { boolValue = value; }
        }

        [DataMember]
        public string StringValue
        {
              get { return stringValue; }
              set { stringValue = value; }
        }
    }
}

Service1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfServiceLibrary1
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in both code and config file together.
    public class Service1 : IService1
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }
    }
}

적당한 위치에 추가하면 다음과 같은 솔루션 구성을 볼 수 있다.

지금까지 구성한 내용은 WCF의 알맹이 부분이라면, 이제 외부에 노출되는 페이지를 만들어야 한다. 즉 ASMX나 ASPX 파일을 만들어야 되는 것이다. WCF에서는 이런 역할을 하는 파일이 SVC 파일이다. 그러나 현재 SharePoint 템플릿에서는 SVC 파일을 독자적으로 추가할 수 없으므로, 텍스트 파일로 추가하여 확장자를 SVC로 변경하는 것이다.

이제 새롭게 열린 파일 안에 다음과 같은 항목을 추가한다.

<%@ ServiceHost Language="C#" Debug="true"
Factory="Microsoft.SharePoint.Client.Services.MultipleBaseAddressBasicHttpBindingServiceHostFactory
,Microsoft.SharePoint.Client.ServerRuntime, Version=14.0.0.0, Culture=neutral
, PublicKeyToken=71e9bce111e9429c"
Service="WcfServiceLibrary1.Service1, $SharePoint.Project.AssemblyFullName$" %>

위의 내용을 추가할 때, Service 항목 내에 위에서 추가한 WCF 메인 모듈의 네임스페이스와 클래스이름을 연결해서 구성한다. (필자는 특별히 바꾼게 없으므로 위와 같이 적었다.)

 

3. 참조(References) 구성

지금까지 파일들을 추가했으면, 이제 WCF를 구성하기 위해 필요한 DLL 참조를 구성해야 한다.

  1. System.ServiceModel
  2. System.ServiceModel.Web
  3. System.Runtime.Serialization
  4. Micosoft.SharePoint.Client.ServerRuntime

1, 2, 3번은 Add Reference를 한 뒤, .NET 탭에서 찾으면 금방 찾을 수 있다. 그런데, 문제는 4번 Assembly다. 저 Assembly는 .NET이나, COM에서 절대 찾을 수 없다. 직접 Folder를 따라가는 수 밖에 없다. 이를 위해서는 Browse 탭으로 넘어간다.

그리고 난 뒤, C:\ –> Windows –> Assembly –> GAC_MSIL –> Micosoft.SharePoint.Client.ServerRuntime –> 14.0.0.0__71e9bce111e9429c –> Microsoft.SharePoint.Client.ServerRuntime.dll 로 들어가서 Microsoft.SharePoint.Client.ServerRuntime.dll을 선택한다.

 

4. Attribute 설정하기.

원래 WCF에서 Address 설정부터, Binding, 인증 처리 등을 설정하기 위해서는 web.config를 통해서 설정하게 된다. 그런데, 현재 구성하려는 SharePoint 패키지 프로젝트에서는 특정 web.config 부분을 일일히 수정할 수 없다. 그것을 .NET Attribute 기능을 이용해서 적용할 수 있다.

이 부분은 구현하는 CS 파일( 위의 예제로 보면, Service1.cs 파일 )에서 적용한다.
여기서 사용하는 Attribute는 BasicHttpBindingServiceMetadataExchangeEndpointAttribute 와 AspNetCompatibilityRequirements 를 사용한다.

적용하는 코드 부분만을 보면 아래와 같다.

Service1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Microsoft.SharePoint.Client.Services;
using System.ServiceModel.Activation;
using Microsoft.SharePoint.Security;

namespace WcfServiceLibrary1
{

   [BasicHttpBindingServiceMetadataExchangeEndpointAttribute]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]   
    public class Service1 : IService1
    {
         public string GetData(int value)
         {
              return string.Format("You entered: {0}", value);
         }

         public CompositeType GetDataUsingDataContract(CompositeType composite)
         {
              if (composite == null)
              {
                       throw new ArgumentNullException("composite");
               }
               if (composite.BoolValue)
               {
                       composite.StringValue += "Suffix";
               }
               return composite;
          }
     }
}

using으로 세가지를 추가하고, class 위에 attribute로 두 개를 추가해주면 된다.

 

5. 프로젝트 파일 설정 변경.

프로젝트 자체가 SharePoint 구성요소에 대한 설정만 자동으로 추가된다. 그래서 WCF의 svc 파일 처리가 불가능하다. 이를 위해서는 수동적인 방법을 통해서 처리해야 한다.

먼저 SharePoint 프로젝트를 Text 파일로 열어 그 안의 XML 파일을 연다. csproj 파일을 메모장 같은 도구로 열면 된다. 그리고 Project –>PropertyGroup 엘리멘트 안에 <TokenReplacementFileExtensions>svc</TokenReplacementFileExtensions> 라는 엘리멘트를 추가하면 된다.

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{6EDE3191-D412-4B0A-917A-09BA91DAD509}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>Nocson.EzSearch</RootNamespace>
    <AssemblyName>Nocson.EzSearch</AssemblyName>
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <ProjectTypeGuids>{BB1F664B-9266-4fd6-B973-E1E44974B511};{14822709-….</ProjectTypeGuids>
    <SandboxedSolution>False</SandboxedSolution>
    <TokenReplacementFileExtensions>svc</TokenReplacementFileExtensions>
    <SccProjectName>SAK</SccProjectName>
    <SccLocalPath>SAK</SccLocalPath>
    <SccAuxPath>SAK</SccAuxPath>
    <SccProvider>SAK</SccProvider>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <De…

저장한 뒤에 해당 프로젝트를 다시 로드 한다.

 

6. 배포 하고 테스트.

SharePoint 프로젝트의 특징은 역시 자동으로 .WSP라는 SharePoint 솔루션으로 만들어 주고 그것을 Debug로 설정한 사이트로 자동으로 업로드 해준다.

배포가 성공적으로 되면 웹사이트에서 http://localhost/_vti_bin/WCFTest.svc/MEX 를 입력한다.(꼭 맨 뒤에 /MEX가 있어야 정상적으로 접속이 가능하다.)

정상적으로 읽어오면 아래와 같은 화면이 뜬다.

 

7. 정리

이 연결하는 작업을 전부 수동으로 만들면 그리 문제 없이 설정하고 구성할 수 있다. 하지만, SharePoint의 솔루션으로 포함시켜서 만들려면 몇 가지 씩 손봐야 된다. 그런데도 굳이 SharePoint의 솔루션으로 작업하는 이유는 나중에 Uninstall이나 업그레이드를 보다 간단하게 수행할 수 있기 때문이다.

위의 글들은 아래의 문서들을 참고로 직접 적용 후 정리했다.

728x90

+ Recent posts

728x90