다음을 통해 공유


방법: 이진 데이터를 스트림으로 액세스(Silverlight 클라이언트)

Open Data Protocol(OData)을 사용하면 데이터 서비스가 피드 자체의 외부에서 이진 데이터를 사용할 수 있도록 설정할 수 있습니다. 미디어 리소스라고 부르는 이러한 이진 데이터는 엔터티(미디어 링크 항목이라고 부름)와 별개이지만 엔터티와 관련이 있습니다. 자세한 내용은 이진 데이터로 작업(WCF Data Services)을 참조하십시오.

이 항목의 절차 및 예제에서는 Northwind 스트리밍 샘플 데이터 서비스에 대한 참조를 추가하고 GetReadStream 메서드를 호출하여 이진 데이터를 OData 서비스의 스트림으로 검색하는 방법을 보여 줍니다. 

응용 프로그램에서 액세스되는 스트리밍 데이터 서비스는 스트리밍을 지원하도록 수정된 Northwind 샘플 데이터 서비스의 특별 버전입니다. 자세한 내용은 스트리밍 공급자(WCF Data Services)를 참조하십시오. Northwind 스트리밍 데이터 서비스 샘플은 MSDN 코드 갤러리 웹 사이트에서 다운로드할 수 있습니다.

참고

Northwind 스트리밍 데이터 서비스의 도메인이 이 항목에 표시된 샘플의 도메인과 다르면 도메인 간 정책 파일을 사용하여 도메인 간 통신을 사용하도록 설정해야 합니다.자세한 내용은 HTTP Communication and Security with Silverlight을 참조하십시오.

Northwind 스트리밍 데이터 서비스 샘플에 참조를 추가하려면

  1. MSDN 코드 갤러리 웹 사이트에서 Northwind 스트리밍 데이터 서비스 샘플을 다운로드하고 샘플 추가 정보 파일의 지침에 따라 IIS에 서비스를 배포합니다.

  2. Silverlight 프로젝트를 마우스 오른쪽 단추로 클릭하고 서비스 참조 추가를 클릭합니다. 

  3. 주소 텍스트 상자에 배포된 Northwind 스트리밍 데이터 서비스에 대한 URI를 입력한 후 이동을 클릭합니다.

  4. 네임스페이스 텍스트 상자에 NorthwindStreaming을 입력하고 확인을 클릭합니다.

    데이터 서비스 리소스에 개체로 액세스하고 상호 작용하는 데 사용되는 데이터 클래스가 포함된 새 코드 파일이 프로젝트에 추가됩니다.

다음 예제는 Silverlight에 대한 StreamingClient 응용 프로그램인 XAML(Extensible Application Markup Language) 페이지에 대한 코드 숨김 페이지에서 가져온 것입니다. 페이지를 로드하면 모든 직원을 반환하는 쿼리 결과를 기준으로 DataServiceCollection<T>이 만들어집니다. 직원을 선택하면 DataServiceContext 인스턴스에서 BeginGetReadStream 메서드가 호출됩니다. 비동기 호출이 완료되면 OnGetReadStreamComplete 핸들러가 호출됩니다. 이 메서드에서는 EndGetReadStream 메서드를 호출하기 위해 디스패처가 사용되고 DataServiceStreamResponse 개체에서 이진 스트림이 액세스됩니다.

Imports System
Imports System.Linq
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Input
Imports System.Windows.Media.Imaging
Imports StreamingClient.NorthwindStreaming
Imports System.Data.Services.Client
Imports System.IO
Partial Public Class MainPage
    Inherits UserControl

    Private context As NorthwindEntities
    Private trackedEmployees As DataServiceCollection(Of Employees)
    Private currentEmployee As Employees
    Private imageSource As BitmapImage
    Private currentResult As IAsyncResult

    ' Replace with the URI of your NorthwindStreaming service implementation.
    Private svcUri As String = _
            "https://localhost/NorthwindStreaming/NorthwindStreaming.svc"

    Public Sub New()
        InitializeComponent()
    End Sub
    Private Sub Window_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ' Instantiate the data service context.
        context = New NorthwindEntities(New Uri(svcUri))

        ' Define a LINQ query for Employees.
        Dim query = From employees In context.Employees _
                    Select employees
        Try
            ' Create a new collection for binding all employees.
            trackedEmployees = New DataServiceCollection(Of Employees)()

            ' Define a handler for the LoadCompleted event of the binding collection.
            AddHandler trackedEmployees.LoadCompleted, _
               AddressOf trackedEmployees_LoadCompleted

            ' Execute the query asynchronously and 
            ' load the results into the collection.
            trackedEmployees.LoadAsync(query)

        Catch ex As InvalidOperationException
            MessageBox.Show(ex.Message)
        End Try
    End Sub
    Private Sub trackedEmployees_LoadCompleted(ByVal sender As Object, ByVal e As LoadCompletedEventArgs)
        If e.Error Is Nothing Then
            ' Load all pages of Orders before binding.
            If trackedEmployees.Continuation IsNot Nothing Then

                ' Load the next page of results.
                trackedEmployees.LoadNextPartialSetAsync()
            Else
                ' Bind the root StackPanel element to the collection
                ' related object binding paths are defined in the XAML.
                LayoutRoot.DataContext = trackedEmployees

                If trackedEmployees.Count = 0 Then
                    MessageBox.Show("Data could not be returned from the data service.")
                End If

                ' Select the first employee in the collection.
                employeesComboBox.SelectedIndex = 0
            End If
                Else
                MessageBox.Show(String.Format("An error has occured: {0}", e.Error.Message))
        End If
    End Sub
    Private Sub employeesComboBox_SelectionChanged(ByVal sender As Object, ByVal e As SelectionChangedEventArgs)

        ' Define the method to call when the asynchronous method completes.
        Dim callback As AsyncCallback = AddressOf OnGetReadStreamComplete

        ' Get the currently selected employee.
        currentEmployee = _
            CType(Me.employeesComboBox.SelectedItem, Employees)

        ' Set the Accept header to the jpeg image content type.
        Dim requestArgs = New DataServiceRequestArgs()
        requestArgs.AcceptContentType = "image/jpeg"

        Try
            ' Start to get the read stream for the media resource for the 
            ' currently selected media link entry.    
            context.BeginGetReadStream(currentEmployee, requestArgs, _
                callback, context)

        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub
    Private Sub OnGetReadStreamComplete(ByVal result As IAsyncResult)
        ' Persist the context from the result.
        currentResult = result

        ' Use the Dispatcher to ensure that the 
        ' asynchronous call returns in the correct thread.
        Dispatcher.BeginInvoke(AddressOf OnGetReadStreamCompleteByDispatcher)
    End Sub
    Private Sub OnGetReadStreamCompleteByDispatcher()

        ' Use the Dispatcher to ensure that the 
        ' asynchronous call returns in the correct thread.
        ' Get the original context back from the result.
        context = CType(currentResult.AsyncState, NorthwindEntities)

        Try
            ' Get the response from the returned context.
            Dim response =
                context.EndGetReadStream(currentResult)

            Using imageStream As MemoryStream = _
                New MemoryStream()

                Dim buffer = New Byte(1000) {}
                Dim count = 0

                ' Read the returned stream into the new memory stream.
                If response.Stream.CanRead Then
                    Do
                        count = response.Stream.Read(buffer, 0, buffer.Length)
                        imageStream.Write(buffer, 0, count)
                    Loop While 0 < count
                End If

                imageStream.Position = 0

                ' Use the returned bitmap stream to create a bitmap image that is 
                ' the source of the image control.
                imageSource = New BitmapImage()
                imageSource.SetSource(imageStream)
                employeeImage.Source = imageSource
            End Using

        Catch ex As DataServiceRequestException
            MessageBox.Show(ex.InnerException.Message)                
        Catch ex As Exception
            MessageBox.Show( _
                String.Format("The requested image for employee '{0}' is not valid.", _
                currentEmployee.LastName))
        End Try
    End Sub    
End Class
using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using StreamingClient.NorthwindStreaming;
using System.Data.Services.Client;
using System.IO;

namespace StreamingClient
{
    public partial class MainPage : UserControl
    {

        private NorthwindEntities context;
        private DataServiceCollection<Employees> trackedEmployees;
        private Employees currentEmployee;
        private BitmapImage imageSource;

        // Replace with the URI of your NorthwindStreaming service implementation.
        private string svcUri =
            "https://localhost/NorthwindStreaming/NorthwindStreaming.svc";

        public MainPage()
        {
            InitializeComponent();
        }


        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // Instantiate the data service context.
            context = new NorthwindEntities(new Uri(svcUri));

            // Define a LINQ query for Employees.
            var query = from employees in context.Employees
                        select employees;

            try
            {
                // Create a new collection for binding all employees.
                trackedEmployees = new DataServiceCollection<Employees>();

                // Define a handler for the LoadCompleted event of the binding collection.
                trackedEmployees.LoadCompleted +=
                    new EventHandler<LoadCompletedEventArgs>(trackedEmployees_LoadCompleted);

                // Execute the query asynchronously and 
                // load the results into the collection.
                trackedEmployees.LoadAsync(query);

            }
            catch (InvalidOperationException ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void trackedEmployees_LoadCompleted(object sender, LoadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                // Load all pages of Orders before binding.
                if (trackedEmployees.Continuation != null)
                {
                    // Load the next page of results.
                    trackedEmployees.LoadNextPartialSetAsync();
                }
                else
                {
                    // Bind the root StackPanel element to the collection;
                    // related object binding paths are defined in the XAML.
                    LayoutRoot.DataContext = trackedEmployees;

                    if (trackedEmployees.Count == 0)
                    {
                        MessageBox.Show("Data could not be returned from the data service.");
                    }

                    // Select the first employee in the collection.
                    employeesComboBox.SelectedIndex = 0;
                }
            }
            else
            {
                MessageBox.Show(string.Format("An error has occured: {0}", e.Error.Message));
            }
        }

        private void employeesComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // Get the currently selected employee.
            currentEmployee =
                (Employees)this.employeesComboBox.SelectedItem;

            // Set the Accept header to the jpeg image content type.
            DataServiceRequestArgs requestArgs = new DataServiceRequestArgs();
            requestArgs.AcceptContentType = "image/jpeg";

            try
            {
                // Start to get the read stream for the media resource for the 
                // currently selected media link entry.    
                context.BeginGetReadStream(currentEmployee, requestArgs, 
                    OnGetReadStreamComplete, context);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void OnGetReadStreamComplete(IAsyncResult result)
        {
            // Use the Dispatcher to ensure that the 
            // asynchronous call returns in the correct thread.
            Dispatcher.BeginInvoke(() =>
                {
                    // Get the original context back from the result.
                    context =
                        result.AsyncState as NorthwindEntities;

                    try
                    {
                        // Get the response from the returned context.
                        DataServiceStreamResponse response = 
                            context.EndGetReadStream(result);

                        using (MemoryStream imageStream =
                            new MemoryStream())
                        {
                            byte[] buffer = new byte[1000];
                            int count = 0;

                            // Read the returned stream into the new memory stream.
                            while (response.Stream.CanRead && (0 < (
                                count = response.Stream.Read(buffer, 0, buffer.Length))))
                            {
                                imageStream.Write(buffer, 0, count);
                            }

                            imageStream.Position = 0;

                            // Use the returned bitmap stream to create a bitmap image that is 
                            // the source of the image control.
                            imageSource = new BitmapImage() ;
                            imageSource.SetSource(imageStream);
                            employeeImage.Source = imageSource;
                        }
                    }
                    catch (DataServiceRequestException ex)
                    {
                        MessageBox.Show(ex.InnerException.Message);
                    }
                    catch (Exception)
                    {
                        MessageBox.Show(
                            string.Format("The requested image for employee '{0}' is not valid.",
                            currentEmployee.LastName));
                    }
                }
            );
        }
    }
}

다음 XAML에서는 이전 예제의 페이지를 정의합니다.

<UserControl x:Class="StreamingClient.MainPage"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" Height="300" Width="400" Loaded="Window_Loaded">
    <Grid Name="LayoutRoot" >
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" Width="Auto" VerticalAlignment="Bottom" Height="50" Margin="0,0,0,250">
            <ComboBox Height="23" Name="employeesComboBox" Margin="50,12,0,12" Width="200" DisplayMemberPath="LastName" ItemsSource="{Binding}" SelectionChanged="employeesComboBox_SelectionChanged" />
        </StackPanel>
        <Image Margin="12,76,12,26" Name="employeeImage" Width="350" Stretch="Fill"/>
    </Grid>
</UserControl>

참고 항목

관련 자료

WCF Data Services (Silverlight)

이진 데이터로 작업(WCF Data Services)