WCF streaming is helpful in all those cases when you need to move a lot of data between the client and the service in a way that keeps memory consumption under control (see Large Data and Streaming on MSDN for more details if you are not familiar with the topic). 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
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
0 comments:
Post a Comment