2

According to the following guide at MSDN, any operations that use streamed transfers can only have one input/output parameter.

Link: http://msdn.microsoft.com/en-us/library/ms731913.aspx (see heading "Restrictions on Streamed Transfers")

I'm using streamed transfers for a WCF service that lets clients/consumers upload files to it. The upload itself works fine, but I need a way of passing two more input parameters along with the Stream object: 'string filename' and 'int userid'.

How would I go about doing this?

rafale
  • 1,704
  • 6
  • 29
  • 43

2 Answers2

4

There´s something called headers that you can use in your datacontract:

Example of the interface:

[ServiceContract]
public interface IFile
{
   [OperationContract]
   Stream DownloadFile(int fileid);

   [OperationContract]
   bool UploadFile(FileUploadMessage request);
}

Put this in a separate file:

[MessageContract]
public class FileUploadMessage
{
[MessageHeader(MustUnderstand = true)]
public int MyInt {get;set;

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

[MessageBodyMember(Order = 1)]
public System.IO.Stream FileByteStream {get;set;}
}
Almund
  • 5,695
  • 3
  • 31
  • 35
  • I get the error "interfaces cannot declare types" when I try adding your code to my ServiceContract. This is what it looks like right now: http://pastebin.com/xaFM4EDN – rafale May 23 '11 at 20:33
  • I moved the MessageContract outside the ServiceContract, and it seems to be compiling now. I'm not sure on how to use the message contract, though. Where do I go from here? Link: http://pastebin.com/ykrvgEfi – rafale May 23 '11 at 21:33
  • Hi! Interfaces cannot declare classes within themselves as you noticed so placing it in a seperate file/class is completely right. Next up you use the class as input parameter to the method as shown in the updated example. Then you would simply use the request.FileByteStream to read from the stream in your service. – Almund May 25 '11 at 12:45
  • Another thing, make sure you dispose the streams on both client and server after usage, otherwise you can end up with some painful leaks. – Almund May 25 '11 at 12:45
  • Doesn't seem to be liked in Silverlight 5. Any hints? – Richard B Aug 01 '12 at 21:35
  • Nopes, can´t help there I´m afraid. I only know that early versions of Silverlight lacked full support for service-operations. – Almund Aug 16 '12 at 05:18
0

I have a somewhat similar problem. I created a test project and used a post I found to successfully create a wcf service call it from another project. I have a solution and the two web projects. One project call the service in the other project using a service reference. I had the ServiceContract and the message contract in the interface file generated by creating a wcf service (the file that start with "I"). All of this worked fine. Then I went to our company's main project. It has a main web project that hosts two silverlight project. However the web project is not really a project but started out life as a website with no project at all. I have assumed that adding the two silverlight projects to the website probably created a solution for all three projects. However I'm not certain how vs2010 sees the main website which I will assume has no pointers to any files as a "real" project would. What happened was when I created the wcf service in the main website and put the ServiceContract and MessageContract into the interface file I got the "interfaces cannot declare types" messge regarding the MessageContract and its child classes. I'm trying to follow your advice onthis post by taking the MessageContract and putting it into another file but I'm not sure what type of file. I tried putting the Message contract into a class (cs file). However the ServiceContract refers to classes in the MessageContract and the ServiceContract is no longer seeing the classes in the MessageContract even though they are public. What type of file should I use to separate the Message contract from the ServiceContract?

Thanks, Fig

  • Declaring them in a separate CS file is fine. Make sure that your contract/interface declarations are in the same namespace as the classes that implement them. Otherwise, they're not visible to each other. – rafale Aug 11 '11 at 08:19