Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Open Data Protocol (OData) permite a un servicio de datos hacer que los datos binarios estén disponibles fuera de la propia fuente. Estos datos binarios, denominados un recurso multimedia, son distintos (aunque están relacionados) que una entidad, que se denomina una entrada de vínculo multimedia. Para obtener más información, vea Trabajar con datos binarios (WCF Data Services).
En el procedimiento y los ejemplos de este tema se muestra cómo agregar una referencia al servicio de datos de ejemplo de transmisión de datos Northwind y llamar al método GetReadStream para recuperar datos binarios como un flujo desde un servicio de OData.
El servicio de datos de transmisión por secuencias al que obtiene acceso la aplicación es una versión especial del servicio de datos de ejemplo Northwind que se ha modificado para admitir la transmisión por secuencias. Para obtener más información, vea Proveedores de transmisión por secuencias (WCF Data Services). El servicio de datos de ejemplo de transmisión por secuencias Northwind se puede descargar desde el sitio web Galería de código de MSDN.
Nota
Cuando el dominio del servicio de datos de transmisión por secuencias Northwind sea distinto del dominio del ejemplo mostrado en este tema, debe habilitar la comunicación entre dominios mediante un archivo de directiva entre dominios.Para obtener más información, vea HTTP Communication and Security with Silverlight.
Para agregar una referencia al servicio de datos de transmisión por secuencias de ejemplo Northwind
Descargue el ejemplo del servicio de datos de transmisión por secuencias Northwind desde el sitio web Galería de código de MSDN y siga las instrucciones del archivo léame del ejemplo para implementar el servicio en IIS.
Haga clic con el botón secundario en el proyecto de Silverlight y, a continuación, haga clic en Agregar referencia de servicio.
En el cuadro de texto Dirección, escriba el URI del servicio de datos de transmisión por secuencias Northwind implementado y, a continuación, haga clic en Ir.
En el cuadro de texto Espacio de nombres, escriba NorthwindStreaming y, a continuación, haga clic en Aceptar.
De este modo se agrega un nuevo archivo de código al proyecto, que contiene las clases de datos que se usan para obtener acceso e interactuar con los recursos del servicio de datos como objetos.
Ejemplo
El ejemplo siguiente procede de la página de código subyacente de una página de lenguaje XAML que es la aplicación StreamingClient para Silverlight. Cuando la página se carga, se crea una DataServiceCollection<T> según el resultado de una consulta que devuelve todos los empleados. Cuando se selecciona un empleado, se llama al método BeginGetReadStream en la instancia de DataServiceContext. Cuando se completa la llamada asincrónica, se llama al controlador OnGetReadStreamComplete. En este método, el distribuidor se usa para invocar el método EndGetReadStream y se obtiene acceso al flujo binario desde el objeto 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));
}
}
);
}
}
}
En el código XAML siguiente se define la página del ejemplo anterior.
<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>