Freigeben über


Vorgehensweise: Zugreifen auf Binärdaten als Datenstrom (Silverlight-Client)

Mit Open Data Protocol (OData) kann ein Datendienst Binärdaten außerhalb des Feeds selbst bereitstellen. Diese Binärdaten, die als Medienressource bezeichnet werden, sind von einer Entität getrennt, aber mit dieser verknüpft ist. Die Entitäten werden als Medienlinkeintrag bezeichnet. Weitere Informationen finden Sie unter Arbeiten mit Binärdaten (WCF Data Services).

Die Verfahren und Beispiele in diesem Thema veranschaulichen, wie ein Verweis auf den Northwind-Beispiel-Streamingdatendienst hinzugefügt und die GetReadStream-Methode aufgerufen wird, um Binärdaten als Datenstrom von einem OData-Dienst abzurufen. 

Der Streamingdatendienst, auf den die Anwendung zugreift, ist eine spezielle Version des Northwind-Beispieldatendiensts, die geändert wurde, um Streaming zu unterstützen. Weitere Informationen finden Sie unter Streaminganbieter (WCF Data Services). Den Northwind-Beispiel-Streamingdatendienst können Sie von der MSDN Code Gallery-Website herunterladen.

Hinweis

Wenn sich die Domäne des Northwind-Streamingdatendiensts von der Domäne unterscheidet, die im Beispiel in diesem Thema verwendet wird, müssen Sie die domänenübergreifende Kommunikation durch Verwenden einer domänenübergreifenden Richtliniendatei aktivieren.Weitere Informationen finden Sie unter HTTP Communication and Security with Silverlight.

So fügen Sie einen Verweis auf den Northwind-Beispiel-Streamingdatendienst hinzu

  1. Laden Sie den Northwind-Beispiel-Streamingdatendienst von der MSDN Code Gallery-Website herunter, und folgen Sie den Anweisungen in der Infodatei des Beispiels, um den Dienst in IIS bereitzustellen.

  2. Klicken Sie mit der rechten Maustaste auf das Silverlight-Projekt, und klicken Sie dann auf Dienstverweis hinzufügen

  3. Geben Sie im Textfeld Adresse den URI für den bereitgestellten Northwind-Streamingdatendienst ein, und klicken Sie auf Gehe zu.

  4. Geben Sie im Textfeld Namespace NorthwindStreaming ein, und klicken Sie auf OK.

    Dadurch wird dem Projekt, das die zum Zugriff auf und zur Interaktion mit Datendienstressourcen als Objekte verwendeten Datenklassen enthält, eine neue Codedatei hinzugefügt.

Beispiel

Das folgende Beispiel stammt aus der CodeBehind-Seite für eine XAML (Extensible Application Markup Language)-Seite, bei der es sich um die StreamingClient-Anwendung für Silverlight handelt. Wenn die Seite geladen wird, wird eine DataServiceCollection<T> basierend auf dem Ergebnis einer Abfrage erstellt, die alle Mitarbeiter zurückgibt. Wenn ein Mitarbeiter ausgewählt wird, wird die BeginGetReadStream-Methode für die DataServiceContext-Instanz aufgerufen. Sobald der asynchrone Aufruf abgeschlossen ist, wird der OnGetReadStreamComplete-Handler aufgerufen. In dieser Methode wird der Dispatcher verwendet, um die EndGetReadStream-Methode aufzurufen, und das DataServiceStreamResponse-Objekt greift auf den Binärdatenstrom zu.

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));
                    }
                }
            );
        }
    }
}

Mit dem folgenden XAML-Code wird die Seite für das vorherige Beispiel definiert.

<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>

Siehe auch

Andere Ressourcen

WCF Data Services (Silverlight)

Arbeiten mit Binärdaten (WCF Data Services)