Working with Binary Data (WCF Data Services)

Important

WCF Data Services has been deprecated and will no longer be available for download from the Microsoft Download Center. WCF Data Services supported earlier versions of the Microsoft OData (V1-V3) protocol only and has not been under active development. OData V1-V3 has been superseded by OData V4, which is an industry standard published by OASIS and ratified by ISO. OData V4 is supported through the OData V4 compliant core libraries available at Microsoft.OData.Core. Support documentation is available at OData.Net, and the OData V4 service libraries are available at Microsoft.AspNetCore.OData.

RESTier is the successor to WCF Data Services. RESTier helps you bootstrap a standardized, queryable, HTTP-based REST interface in minutes. Like WCF Data Services before it, Restier provides simple and straightforward ways to shape queries and intercept submissions before and after they hit the database. And like Web API + OData, you still have the flexibility to add your own custom queries and actions with techniques you're already familiar with.

The WCF Data Services client library enables you to retrieve and update binary data from an Open Data Protocol (OData) feed in one of the following ways:

  • As a primitive type property of an entity. This is the recommended method for working with small binary data objects that can be easily loaded into memory. In this case, the binary property is an entity property exposed by the data model, and the data service serializes the binary data as base-64 binary encoded XML in the response message.

  • As a separate binary resource stream. This is the recommended method for accessing and changing binary large object (BLOB) data that may represent a photo, video, or any other type of binary encoded data.

WCF Data Services implements the streaming of binary data by using HTTP as defined in the OData. In this mechanism, binary data is treated as a media resource that is separate from but related to an entity, which is called a media link entry. For more information, see Streaming Provider.

Tip

For a step-by-step example of how to create a Windows Presentation Foundation (WPF) client application that downloads binary image files from an OData service that stores photos, see the post Data Services Streaming Provider Series-Part 2: Accessing a Media Resource Stream from the Client. To download the sample code for the stream photo data service featured in the blog post, see the Streaming Photo Data Service Sample in GitHub.

Entity Metadata

An entity that has a related media resource stream is indicated in the data service metadata by the HasStream attribute applied to an entity type that is the media link entry. In the following example, the PhotoInfo entity is a media link entry that has a related media resource, indicated by the HasStream attribute.

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

The remaining examples in this topic show how to access and change the media resource stream. For a complete example of how to consume a media resource stream in a .NET Framework client application by using the WCF Data Services client library, see the post Accessing a Media Resource Stream from the Client.

Accessing the Binary Resource Stream

The WCF Data Services client library provides methods for accessing binary resource streams from an OData-based data service. When downloading a media resource, you can either use the URI of the media resource or you can get a binary stream that contains the media resource data itself. You can also upload media resource data as a binary stream.

Tip

For a step-by-step example of how to create a Windows Presentation Foundation (WPF) client application that downloads binary image files from an OData service that stores photos, see the post Data Services Streaming Provider Series-Part 2: Accessing a Media Resource Stream from the Client. To download the sample code for the stream photo data service featured in the blog post, see the Streaming Photo Data Service Sample in GitHub.

Getting the URI of the Binary Stream

When retrieving certain types of media resources, such as images and other media files, it is often easier to use the URI of the media resource in your application than handling the binary data stream itself. To get the URI of a resource stream associated with a give media link entry, you must call the GetReadStreamUri method on the DataServiceContext instance that is tracking the entity. The following example shows how to call the GetReadStreamUri method to get the URI of a media resource stream that is used to create a new image on the client:

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

Downloading the Binary Resource Stream

When retrieving a binary resource stream, you must call the GetReadStream method on the DataServiceContext instance that is tracking the media link entry. This method sends a request to the data service that returns a DataServiceStreamResponse object, which has a reference to the stream that contains the resource. Use this method when your application requires the binary resource as a Stream. The following example shows how to call the GetReadStream method to retrieve a stream that is used to create a new image on the client:

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

Note

The Content-Length header in the response message that contains the binary steam is not set by the data service. This value may not reflect the actual length of the binary data stream.

Uploading a Media Resource as a Stream

To insert or update a media resource, call the SetSaveStream method on the DataServiceContext instance that is tracking the entity. This method sends a request to the data service that contains the media resource read from the supplied stream. The following example shows how to call the SetSaveStream method to send an image to the data service:

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

In this example, the SetSaveStream method is called by supplying a value of true for the closeStream parameter. This guarantees that the DataServiceContext closes the stream after the binary data is uploaded to the data service.

Note

When you call SetSaveStream, the stream is not sent to the data service until SaveChanges is called.

See also