Работа с двоичными данными (службы WCF Data Services)

Клиентская библиотека Службы WCF Data Services позволяет извлекать и обновлять двоичные данные из канала Протокол Open Data Protocol (OData) одним из следующих способов:

  • В качестве свойства сущности примитивного типа. Этот метод рекомендуется использовать при работе с небольшими двоичными объектами данных, которые могут быть легко загружены в память. В этом случае двоичное свойство представляет собой свойство сущности, предоставленное моделью данных, служба данных сериализует двоичные данные в ответном сообщении как XML-элемент с двоичной кодировкой с базой 64.

  • В качестве отдельного потока двоичных данных. Этот метод рекомендуется использовать для доступа и изменения данных больших двоичных объектов, которые могут представлять фото, видео или другие типы данных с двоичной кодировкой.

Службы WCF Data Services реализует потоковую передачу двоичных данных с использованием HTTP, как определено в протоколе OData. OData обеспечивает следующие потоковые механизмы для связывания двоичных данных с сущностью.

  • Ресурс мультимедиа/запись ссылки мультимедиа

    Протокол публикации Atom (AtomPub) определяет механизм для связывания двоичных данных как мультимедийный ресурс с записью в потоке данных, который называется запись ссылки мультимедиа. Может существовать только один ресурс мультимедиа, определенные для данной записи ссылки мультимедиа. Ресурс мультимедиа может рассматриваться как поток по умолчанию для сущности. OData наследует это потоковое поведение от AtomPub.

  • Именованный поток ресурсов

    Начиная с версии 3 OData, сущность может иметь несколько связанных потоков ресурсов, доступ к которым осуществляется по имени. Этот механизм не зависит от AtomPub, поэтому сущность может иметь потоки именованных ресурсов и не являться записью ссылки мультимедиа. Запись ссылки мультимедиа также может иметь именованные потоки. Дополнительные сведения см. в разделе Потоковый поставщик (службы WCF Data Services).

Метаданные сущности

Сущность, которая имеет связанные потоки двоичных ресурсов, отмечается в метаданных службы данных одним из следующих способов, в зависимости от типа потока.

  1. Ресурс мультимедиа.

    Атрибут HasStream — тип сущности, который является записью ссылки мультимедиа.

  2. Именованный поток ресурсов.

    Одно или несколько свойств сущности в модели данных, которые принадлежат к типу данных Stream.

    Поддержка типа данных Stream в модели данных требует версии EDM 2.2. Дополнительные сведения см. в разделе Streaming Provider (WCF Data Services).

В следующем примере сущность PhotoInfo представляет собой запись ссылки мультимедиа, которая имеет как связанный ресурс мультимедиа, обозначаемый атрибутом HasStream, так и именованный поток ресурсов с именем Thumbnail.

<EntityType Name="PhotoInfo" m:HasStream="true">
  <Key>
    <PropertyRef Name="PhotoId" />
  </Key>
  <Property Name="PhotoId" Type="Edm.Int32" Nullable="false" 
            p9:StoreGeneratedPattern="Identity" 
            xmlns:p9="https://schemas.microsoft.com/ado/2009/02/edm/annotation" />
  <Property Name="FileName" Type="Edm.String" Nullable="false" />
  <Property Name="FileSize" Type="Edm.Int32" Nullable="true" />
  <Property Name="DateTaken" Type="Edm.DateTime" Nullable="true" />
  <Property Name="TakenBy" Type="Edm.String" Nullable="true" />
  <Property Name="DateAdded" Type="Edm.DateTime" Nullable="false" />
  <Property Name="Exposure" Type="PhotoData.Exposure" Nullable="false" />
  <Property Name="Dimensions" Type="PhotoData.Dimensions" Nullable="false" />
  <Property Name="DateModified" Type="Edm.DateTime" Nullable="false" />
  <Property Name="Comments" Type="Edm.String" Nullable="true" MaxLength="Max" 
            Unicode="true" FixedLength="false" />
  <Property Name="ContentType" Type="Edm.String" Nullable="true" MaxLength="50" 
            Unicode="true" FixedLength="false" />
  <Property Name="Thumbnail" Type="Edm.Stream" Nullable="false" />
</EntityType>

В остальных примерах этого раздела описываются способы доступа к потоку медиаресурса и его изменения. Полный пример получения потока медиаресурса в клиентском приложении .NET Framework с помощью клиентской библиотеки Службы WCF Data Services см. в сообщении Получение доступа к потоку медиаресурса с клиента.

Доступ к потокам двоичных ресурсов

Клиентская библиотека Службы WCF Data Services предоставляет методы доступа к потокам двоичных данных из службы данных на основе OData. При загрузке медиаресурса вы можете использовать URI-идентификатор медиаресурса или получить двоичный поток, непосредственно содержащий данные медиаресурса. Вы можете также загрузить данные медиаресурса в виде двоичного потока.

Совет

Пошаговые инструкции по созданию клиентского приложения Windows Presentation Foundation (WPF), загружающего двоичные файлы изображений из службы OData, которая хранит изображения, см. в сообщении Последовательности поточных поставщиков служб данных, часть 2. Доступ к потоку медиаресурса с клиента.Сведения о загрузке образца кода для потоковой службы данных с изображениями, о которой идет речь в сообщении блога, см. в разделе Образец потоковой службы данных с изображениями на сайте MSDN Code Gallery.

Получение URI-идентификатора двоичного потока

При получении определенных типов медиаресурсов, таких как изображения и другие медиафайлы, часто бывает проще использовать URI-идентификатор приложения, чем обрабатывать непосредственно поток двоичных данных. Чтобы получить URI-идентификатор потока ресурса, связанный с определенной ссылкой на данные, следует вызвать метод GetReadStreamUri(Object) для экземпляра DataServiceContext, который отслеживает сущность. Чтобы получить URI именованного потока ресурсов, следует вызвать перегрузку метода, которая принимает параметр name, представляющий собой имя потока. В этом примере показан порядок вызова метода GetReadStreamUri(Object), получающего URI-идентификатор потока медиаресурса, который используется для создания нового изображения на стороне клиента.

' Use the ReadStreamUri of the Media Resource for selected PhotoInfo object
' as the URI source of a new bitmap image.
photoImage.Source = New BitmapImage(context.GetReadStreamUri(currentPhoto))
// Use the ReadStreamUri of the Media Resource for selected PhotoInfo object
// as the URI source of a new bitmap image.
photoImage.Source = new BitmapImage(context.GetReadStreamUri(currentPhoto));

Для именованных потоков ресурсов также вы можете получить URI потока непосредственно из свойства потока. Для каждого свойства записи ссылки мультимедиа, возвращаемого метаданными службы данных, которое имеет тип Stream, средства службы данных создают свойство, возвращающее экземпляр DataServiceStreamLink. Свойство Uri этого DataServiceStreamLink представляет собой URI именованного потока ресурсов. Это позволяет получить URI непосредственно из объекта записи ссылки мультимедиа или как результат запроса LINQ.

Загрузка двоичного потока ресурса

При получении двоичного потока ресурса следует вызвать метод GetReadStream для экземпляра DataServiceContext, который отслеживает ссылку на данные. Этот метод отправляет запрос службе данных, возвращающей объект DataServiceStreamResponse, который содержит ссылку на поток, содержащий медиаресурс. Этот метод используется, если приложение требует двоичный файл ресурса в виде Stream. При доступе к именованному потоку ресурсов следует вызвать перегрузку метода, которая принимает параметр name, представляющий собой имя потока. В следующем примере показано, как вызвать метод GetReadStream для получения потока, используемого для создания нового изображения на стороне клиента.

' Get the read stream for the Media Resource of the currently selected 
' entity (Media Link Entry).
Using response As DataServiceStreamResponse = _
        context.GetReadStream(currentEmployee, "image/bmp")

    ' Use the returned binary stream to create a bitmap image that is 
    ' the source of the image control.
    employeeImage.Source = CreateBitmapFromStream(response.Stream)
End Using
// Get the read stream for the Media Resource of the currently selected 
// entity (Media Link Entry).
using (DataServiceStreamResponse response =
    context.GetReadStream(currentEmployee, "image/bmp"))
{
    // Use the returned binary stream to create a bitmap image that is 
    // the source of the image control.
    employeeImage.Source = CreateBitmapFromStream(response.Stream);
}

Примечание

Заголовок Content-Length в ответном сообщении, в котором содержится поток двоичных данных, не заданный службой данных.Это значение может не отражать фактическую длину потока двоичных данных.

Передача медиаресурса в виде потока

Чтобы вставить или обновить медиаресурс, вызовите метод SetSaveStream для экземпляра DataServiceContext, который отслеживает сущность. Этот метод отправляет запрос службе данных, содержащей медиаресурс, считанный из предоставленного потока. При передаче именованного потока ресурсов следует вызвать перегрузку метода, которая принимает параметр name, представляющий собой имя потока ресурсов. В следующем примере описывается способ вызова метода SetSaveStream для отправки битовой карты, принадлежащей определенному сотруднику, службе данных:

' Set the file stream as the source of binary stream 
' to send to the data service. The Slug header is the file name and
' the content type is determined from the file extension. 
' A value of 'true' means that the stream is closed by the client when 
' the upload is complete.
context.SetSaveStream(photoEntity, imageStream, True, _
    photoEntity.ContentType, photoEntity.FileName)
// Set the file stream as the source of binary stream 
// to send to the data service. The Slug header is the file name and
// the content type is determined from the file extension. 
// A value of 'true' means that the stream is closed by the client when 
// the upload is complete.
context.SetSaveStream(photoEntity, imageStream, true,
    photoEntity.ContentType, photoEntity.FileName);

В этом примере метод SetSaveStream вызывается с помощью присвоения значения true параметру closeStream. Благодаря этому объект DataServiceContext гарантированно закрывает поток после загрузки двоичных данных в службу данных.

Примечание

При вызове метода SetSaveStream(Object, String, Stream, Boolean, String) поток не отправляется в службу данных, пока не будет вызван метод SaveChanges.

См. также

Основные понятия

Привязка данных к элементам управления (службы WCF Data Services)

Другие ресурсы

Данные клиента (WCF Data Services)