1

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..

Ichiro Satoshi
  • 301
  • 1
  • 8
  • 17
  • I don't see anything recursive - I see an array of Message Contracts in your service operation, but that should be ok. – Tim Oct 26 '11 at 05:49
  • I'm sorry Tim, I mean can we use a MessageContract as another MessageContract member ? I need a messagecontract which one of it's member is an array of another messagecontract.. – Ichiro Satoshi Oct 26 '11 at 07:04
  • Off the top of my head I don't see why not. I can't give you a 100% sure you can or sure you can't answer though. Have you tried it to see if it works? – Tim Oct 26 '11 at 07:06

2 Answers2

3

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.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
1

Quick answer: no, you can't. Message contract is a top-level definition of a SOAP message, not something which can be composed. In your example, you define the Files member to be in the body, but some of its properties (FileName, FileSize) to be in the header which is not consistent. If you try that it may even "work", in a way that you won't see any errors, but just because WCF will be treating the FileUploadInputParameter type as a POCO serializable type.

carlosfigueira
  • 85,035
  • 14
  • 131
  • 171