Question

Is it possible to stream a file using WCF with a MessageContract that contains another MessageContract that has the Stream inside it? I think the answer is no, but I'd much prefer to package my file inside a "Root" message so to speak.

In otherwords my setup is like this:

[MessageContract]
public class Transport
{
    [MessageHeader]
    private readonly Guid fId;

    [MessageHeader]
    private readonly DateTime fTimestamp;

    [MessageBodyMember(Order = 1)]
    public FileTransferMessage FileTransferMessage { get; set; }
}

[MessageContract]
public class FileTransferMessage : IDisposable
{
    [MessageBodyMember(Order = 1)]
    public Stream FileByteStream;

    [MessageHeader(MustUnderstand = true)]
    public long FileLength;

    [MessageHeader(MustUnderstand = true)]
    public string FileName;
}

The request is sent and received to the service just fine, however, it appears the Stream is not being deserialized properly and coming back as null reference. I know I've read a rule somewhere that states on a MessageContract with Streaming that the Stream MUST be the Body of the MessageContract, and I'm thinking that is what is being violated right now. I was hoping that the FileTransferMessage being the Body and then the Stream being the Body of that would be acceptable.

Anyone have any suggestions on what I can do here? I'd prefer NOT to add a Stream/FileName/FileLength to my Transport object.

Was it helpful?

Solution

As someone who was part of the team designing MessageContract, I can tell you that the answer is no :) MessageContract represents exactly one full SOAP message, you can't nest them in each other (the FileTransferMessage in your example is simply handed to the serializer, which knows nothing about the [MessageContract] attribute and ignores it, and knows nothing about any special Stream behavior).

Short of creating a custom Message subclass (or even a custom Stream subclass), I can't think of a good solution. If fId and fTimestamp are on every message, consider using a custom Message Inspector to inject these, and then just use FileTransferMessage in your operation.

Authoritative documents here are http://msdn.microsoft.com/en-us/library/ms730255.aspx and http://msdn.microsoft.com/en-us/library/ms733742.aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top