1.     WCF 서비스를 구동시키기

-       서비스를 담당할 전담 웹사이트 프로젝트를 만듭니다.


-       저장 위치를 지정하고, WCF 서비스 항목을 선택합니다.


-       App_Code폴더와 그 안에 IService.cs, Service.cs 파일 그리고, Service.svc 파일이 자동 생성된 것을 볼 수 있는데, 서비스 구현은 이미 했기 때문에 Service.svc파일을 제외한 두 개의 파일들을 과감하게 삭제 해버립니다.


-       참조 추가 항목을 선택하고, WCF서비스 라이브러리 프로젝트 항목을 선택합니다. 그리고, Bin 폴더에 dll이 잘 추가된 것을 볼 수 있습니다.

 

-       Service.svc 파일을 수정합니다.

자동 생성되었던 Service.svc

<%@ ServiceHost Language="C#" Debug="true" Service="Service" CodeBehind="~/App_Code/Service.cs" %>

 

수정된 Service.svc

<%@ ServiceHost Debug="true" Language="C#" Service="WCFServiceLibrary.ProductService" %>

ð  기존 파일에는 Service태그에 클래스명을 지정되어 있고, CodeBehind에 해당 코드 주소를 입력하였으나, 별도의 컴포넌트로 구현하였기에, 컴포넌트 이름에 해당 서비스 클래스명을 지정해 주면 됩니다.

-       Web.config 수정하여야 하는데, 전에 app.config 파일을 WCF 구성 편집 항목을 통해 수정해 본 적이 있습니다. 그 방식과 같이 WCF서비스 구성을 편집합니다. (9번 항목)

-       Web.config 파일을 열어 보면 <system.serviceModel>부분을 제외하고 나머지는 과감하게 삭제해버립니다.

Web.config

<?xml version="1.0" encoding="utf-8"?>

<configuration>

  <system.serviceModel>

    <behaviors>

      <serviceBehaviors>

        <behavior name="ServiceBehavior">

          <serviceMetadata httpGetEnabled="true" />

          <serviceDebug includeExceptionDetailInFaults="false" />

        </behavior>

      </serviceBehaviors>

    </behaviors>

    <services>

      <service behaviorConfiguration="ServiceBehavior" name="WCFServiceLibrary.ProductService">

        <endpoint address="" binding="basicHttpBinding" bindingConfiguration=""

          contract="WCFServiceLibrary.IProductService">

          <identity>

            <dns value="localhost" />

          </identity>

        </endpoint>

        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

      </service>

    </services>

  </system.serviceModel>

</configuration>

-       WCFServiceWebSite 웹사이트의 속성에 가상 경로가 “/”가 아닌 다른 경로가 지정된 경우가 있는데, “/”로 수정합니다. 조금 있다 알게 되겠지만, 정책 파일을 찾는 경로는 웹사이트 최상위 루트이기 때문에 바꿔주어야 합니다.

 

-       Service.svc브라우저에서 보기 항목을 선택하여 잘 구동되는지를 확인합니다.


-       WCF 테스트 브라우저 창을 통해 WCF 서비스 역할이 잘 작동하는지 확인한 적이 있습니다. 웹사이트에서도 잘 되는지 확인하겠습니다. Visual Studio 2008 명령 프롬프트를 선택하고, cmd창이 나타나는 것을 볼 수 있습니다. (cmd창에서 Visual Studio 2008 설치 경로\VC로 들어가시면 됩니다. 기본 설치시 C:\Program Files\Microsoft Visual Studio 9.0\VC 입니다.)


-       좀 전에 svc 파일을 브라우저에서 봤었는데, cmd창에 명령어를 “wcfTestClient + 브라우저에서 봤던 url”를 입력하시면 WCF 테스트 브라우저 창이 나타나며, 전에 했던 방식으로 서비스 역할 테스트를 해보시면 됩니다. (부가 설명은 하지 않겠습니다.)


2.     Silverlight 응용 프로그램 만들기 (위에서 설명한 바가 있어, 자세한 설명은 하지 않겠습니다)

-       솔루션에 새 프로젝트 추가 한 후, 프로젝트명과 저장 경로를 지정하고, Silverlight 응용 프로그램을 선택합니다.

-       Silverlight를 호스팅할 웹 사이트 지정하는 브라우저 창이 나타나며, WCFServiceWebSite WCF 서비스 전담으로 만든 프로젝트이므로, “솔루션에 Silverlight를 호스팅할 새 ASP.NET 웹 프로젝트 추가항목을 선택하여 웹 사이트를 추가합니다.

-       Silverlight 영역에 DataGrid 컨트롤 및 각 이벤트의 버튼을 추가하여 UI을 구상합니다. Microsoft Blend2를 실행시켜 디자인 작업하면 손쉽게 진행할 수 있습니다.

Code

Page.xaml

<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"  x:Class="SilverlightApplication.Page"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >

    <Grid x:Name="LayoutRoot" Background="White">

        <Grid.RowDefinitions>

            <RowDefinition Height="60"></RowDefinition>

            <RowDefinition Height="*"></RowDefinition>

        </Grid.RowDefinitions>

       

<StackPanel Orientation="Horizontal" Grid.Row="0">

            <Button x:Name="btnSelect" Width="60"  Height="35" Margin="5" Content="보기"></Button>

            <Button x:Name="btnInsert" Width="60"  Height="35" Margin="5" Content="추가"></Button>

            <Button x:Name="btnUpdate" Width="60"  Height="35" Margin="5" Content="수정"></Button>

            <Button x:Name="btnDelete" Width="60"  Height="35" Margin="5" Content="삭제"></Button>

        </StackPanel>

<data:DataGrid Grid.Row="1"></data:DataGrid>

    </Grid>

</UserControl>

-       Silverlight 응용 프로젝트에 WCF 서비스를 참조합니다. 좀전에 WCF 서비스 전담 웹사이트에서의 svc 파일 URL을 주소에 입력하고 이동하면, 문제가 없다면 인터페이스 목록이 나타납니다. 그리고 서비스 참조 네임스페이스를 입력하고 추가합니다.


-       UI 구성 및 서비스 참조가 완료한 후, 모든 버튼의 이벤트 함수를 구현하기에 앞 서, “보기 버튼에 대한 이벤트를 구현해보겠습니다.

Code

Page.xaml

<!-- 생략 -->

<StackPanel Orientation="Horizontal" Grid.Row="0">

    <Button x:Name="btnSelect" Width="60"  Height="35" Margin="5" Content="보기" Click="btnSelect_Click"></Button>

    <Button x:Name="btnInsert" Width="60"  Height="35" Margin="5" Content="추가" Click="btnInsert_Click"></Button>

    <Button x:Name="btnUpdate" Width="60"  Height="35" Margin="5" Content="수정" Click="btnUpdate_Click"></Button>

    <Button x:Name="btnDelete" Width="60"  Height="35" Margin="5" Content="삭제" Click="btnDelete_Click"></Button>

</StackPanel>

<data:DataGrid Grid.Row="1" x:Name="dlResult" Background="Beige"></data:DataGrid>

<!-- 생략 -->

 

Page.xaml.cs

public partial class Page : UserControl

{

    ProductDBService.ProductServiceClient serivce = new ProductDBService.ProductServiceClient();

 

    public Page()

    {

        InitializeComponent();

    }

 

    private void btnSelect_Click(object sender, RoutedEventArgs e)

    {

        serivce.SelectProductAsync();

        serivce.SelectProductCompleted += new EventHandler<SelectProductCompletedEventArgs>(serivce_SelectProductCompleted);

    }

 

    void serivce_SelectProductCompleted(object sender, SelectProductCompletedEventArgs e)

    {

        dlResult.ItemsSource = e.Result;

    }

 

    private void btnInsert_Click(object sender, RoutedEventArgs e) {  }

 

    private void btnUpdate_Click(object sender, RoutedEventArgs e) {  }

 

    private void btnDelete_Click(object sender, RoutedEventArgs e) {  }

}

Description

ð  WCF 서비스에 노출된 서비스를 보면, Async 함수와 Completed 이벤트를 가지게 되는 것을 볼 수 있습니다. 간단히 설명드리면, Async 함수로 필요한 인자를 넣고 실행시키면, Completed 이벤트 함수에서 Result(WCF 서비스 호출한 데이터)를 보내주는 방식입니다.


ð  DataList 컨트롤에 서비스 호출하여 Select한 데이터를 바인딩한 후, 잘 동작하는 지 실행(F5)합니다. 하지만, 아래와 같은 오류가 발생하는 것을 볼 수 있으며, IE 개발 툴인 HttpWatch, Fidder, WebDevHelper 등을 이용하여 조회하여 보면, 2개의 파일에서 404. 파일이 없다는 결과를 볼 수 있습니다.


ð  Silverlight는 크로스 도메인에 대해서 제약이 되어 있다고 설명한 바가 있습니다. 크로스 도메인 접근을 위해서는 웹사이트의 최상위 루트 디렉토리에 보안 정책 파일인 clientaccesspolicy.xml 파일과 crossdomain.xml 파일을 배포하여야 합니다.

(참고 : Silverlight 2.0 Tutorial)

-       보안 정책 파일을 WCF 서비스 웹사이트의 최상위 루트에 배포한 후, 다시 실행하면, 잘 작동하는 것을 볼 수 있습니다.


-       마지막으로 남은 버튼의 이벤트도 구현하겠습니다.

Code

public partial class Page : UserControl

{

    ProductDBService.ProductServiceClient serivce = new ProductDBService.ProductServiceClient();

 

    public Page()

    {

        InitializeComponent();

    }

 

    private void btnSelect_Click(object sender, RoutedEventArgs e)

    {

        serivce.SelectProductAsync();

        serivce.SelectProductCompleted += new EventHandler<SelectProductCompletedEventArgs>(serivce_SelectProductCompleted);

    }

 

    void serivce_SelectProductCompleted(object sender, SelectProductCompletedEventArgs e)

    {

        dlResult.ItemsSource = e.Result;

    }

 

    private void btnInsert_Click(object sender, RoutedEventArgs e)

    {

        Products product = new Products();

        product.ProductName = "TEST";

 

        serivce.InsertProductAsync(product);

        serivce.InsertProductCompleted += new EventHandler<InsertProductCompletedEventArgs>(serivce_InsertProductCompleted);

    }

 

    void serivce_InsertProductCompleted(object sender, InsertProductCompletedEventArgs e)

    {

        Refresh(e.Result);

    }

 

    private void btnUpdate_Click(object sender, RoutedEventArgs e)

    {

        serivce.UpdateProductAsync(dlResult.SelectedItem as Products);

        serivce.UpdateProductCompleted += new EventHandler<UpdateProductCompletedEventArgs>(serivce_UpdateProductCompleted);

    }

 

    void serivce_UpdateProductCompleted(object sender, UpdateProductCompletedEventArgs e)

    {

        Refresh(e.Result);

    }

 

    private void btnDelete_Click(object sender, RoutedEventArgs e)

    {

        serivce.DeleteProductAsync((dlResult.SelectedItem as Products).ProductName);

        serivce.DeleteProductCompleted += new EventHandler<DeleteProductCompletedEventArgs>(serivce_DeleteProductCompleted);

    }

 

    void serivce_DeleteProductCompleted(object sender, DeleteProductCompletedEventArgs e)

    {

        Refresh(e.Result);

    }

 

    private void Refresh(bool result)

    {

        if (result)

        {

            MessageBox.Show("작업 완료 되었습니다.");

            serivce.SelectProductAsync();

        }

        else

        {

            MessageBox.Show("작업 실패하였습니다.");

        }

    }

}

Description

ð  각 버튼의 이벤트를 구현하였으며, 추가, 수정, 삭제 시 리플래시하였습니다.

 

 

l  참고 사이트

-       MSDN Library (WCF)

http://msdn.microsoft.com/ko-kr/library/ms735119.aspx

 

+ Recent posts