Search code examples
c#.netwcfsoapmessagecontract

Put a MessageContract as MessageBodyMember in other contract in WCF


Can I use recursive MessageContract in WCF ? for example :

I need to post some parameters, one of the parameters is an array of file stream. this is My OperationContract :

DomainResult AddSomethingNew(int externalCustomerId, string domainName, bool isDefault, FileDataContract[] files);

here is my MessageContract :

[MessageContract]
public class FileDataContract
{        
    [MessageHeader(MustUnderstand=true)]
    public int ExternalCustomerId { get; set; }

    [MessageHeader(MustUnderstand=true)]
    public string DomainName{get;set;}

    [MessageHeader(MustUnderstand=true)]
    public bool IsDefault{get;set;}

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

[MessageContract]
public class FileUploadInputParameter
{
    [MessageHeader(MustUnderstand = true)]
    public string FileName { get; set; }

    [MessageHeader(MustUnderstand = true)]
    public decimal FileSize { get; set; }

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

need your helps..


Solution

  • You can use inheritance to define relation between two message contracts:

    [MessageContract]
    public class FileUploadInputParameter
    {
        [MessageHeader(MustUnderstand = true)]
        public string FileName { get; set; }
    
        [MessageHeader(MustUnderstand = true)]
        public decimal FileSize { get; set; }
    
        [MessageBodyMember(Order = 1)]
        public Stream FileStream { get; set; }
    }
    
    [MessageContract]
    public class FileDataContract : FileUploadInputParameter
    {        
        [MessageHeader(MustUnderstand=true)]
        public int ExternalCustomerId { get; set; }
    
        [MessageHeader(MustUnderstand=true)]
        public string DomainName{get;set;}
    
        [MessageHeader(MustUnderstand=true)]
        public bool IsDefault{get;set;}
    }
    

    You cannot define message contract as you described in FileDataContract because you cannot have array of message headers and more over Stream can be in most cases the only available body element and it must be only one. So if you need to pass multiple files you should also implement some compression (zip) and send single stream.