HOW TO:以資料流形式存取二進位資料 (Silverlight 用戶端)
Open Data Protocol (OData) 可讓資料服務將二進位資料提供給摘要本身外部使用。 此二進位資料 (稱為媒體資源) 與實體分開但還是與實體有關 (實體稱為媒體連結項目)。如需詳細資訊,請參閱使用二進位資料 (WCF Data Services)。
本主題的程序和範例為您示範如何加入 Northwind 資料流範例資料服務的參考,並以 OData 服務中的資料流形式呼叫 GetReadStream 方法來擷取二進位資料。
應用程式所存取的資料流資料服務是特殊版本的 Northwind 範例資料服務,此版本已經過修改,所以可支援資料流。 如需詳細資訊,請參閱資料流處理提供者 (WCF Data Services)。 Northwind 資料流資料服務範例可以從 MSDN Code Gallery 網站下載。
注意
當 Northwind 資料流資料服務的網域與本主題所示之範例的網域不同時,您必須使用跨網域原則檔案來啟用跨網域通訊。如需詳細資訊,請參閱 HTTP Communication and Security with Silverlight。
若要加入 Northwind 資料流資料服務範例的參考
從 MSDN Code Gallery 網站下載 Northwind 資料流資料服務範例,並依照範例讀我檔案中的指示在 IIS 上部署此服務。
以滑鼠右鍵按一下 Silverlight 專案,並按一下 [加入服務參考]。
在 [位址] 文字方塊中,輸入已部署之 Northwind 資料流資料服務的 URI,然後按一下 [移至]。
在 [命名空間] 文字方塊中,輸入 NorthwindStreaming,然後按一下 [確定]。
這會將新的程式碼檔案加入至專案中,此專案包含的資料類別可用來存取做為物件的資料服務資源,並與之進行互動。
範例
下列範例取自可延伸應用程式標記語言 (XAML) 頁面的程式碼後置頁面,此 XAML 頁面為 Silverlight 適用的 StreamingClient 應用程式。 當載入此頁面時,將會根據傳回所有員工的查詢結果建立 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>