Streaming does impose some restrictions. Among them is that your operations can only have one input and/or output parameter and they can only be only one of the following:
a Stream
a Message
a class implementing IXmlSerializable
I wanted to expose a very simple service to upload and download files through WCF. And because I wanted to be able to pass both the file content as a stream and at least the file name, I could not just use a Stream but had to resort to using Messages: the headers would convey the file information (such as the file type) and the body the content of the file itself through a stream.
I therefore defined the service as follows:
[ServiceContract(Namespace = "http://schemas.acme.it/2009/04")]
public interface IFileTransferService
{
[OperationContract(IsOneWay = true)]
void UploadFile(FileUploadMessage request);
[OperationContract(IsOneWay = false)]
FileDownloadReturnMessage DownloadFile(FileDownloadMessage request);
}
[MessageContract]
public class FileUploadMessage
{
[MessageHeader(MustUnderstand = true)]
public FileMetaData Metadata;
[MessageBodyMember(Order = 1)]
public Stream FileByteStream;
}
[MessageContract]
public class FileDownloadMessage
{
[MessageHeader(MustUnderstand = true)]
public FileMetaData FileMetaData;
}
[MessageContract]
public class FileDownloadReturnMessage
{
public FileDownloadReturnMessage(FileMetaData metaData, Stream stream)
{
this.DownloadedFileMetadata = metaData;
this.FileByteStream = stream;
}
[MessageHeader(MustUnderstand = true)]
public FileMetaData DownloadedFileMetadata;
[MessageBodyMember(Order = 1)]
public Stream FileByteStream;
}
[DataContract(Namespace = "http://schemas.acme.it/2009/04")]
public class FileMetaData
{
public FileMetaData(
string localFileName,
string remoteFileName)
{
this.LocalFileName = localFileName;
this.RemoteFileName = remoteFileName;
this.FileType = FileTypeEnum.Generic;
}
public FileMetaData(
Read more: Stefano Ricciardi