Working with Binary Data (WCF Data Services)
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 (WCF Data Services).
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 MSDN Code Gallery. |
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 MSDN Code Gallery. |
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:
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
Concepts
Binding Data to Controls (WCF Data Services)