One of the problems with the mono framework is that streaming is not working properly. I tried to get it working myself and even tried to fix the framework myself. To much trouble as the solution is to use another approach called REST.
REST uses the url to submit parameters and the HTTP methods (GET, POST, PUT, DELETE) The supplied information is used to map te request to a service operation. Below is a sample of how to stream a file from a dotNET hosted REST service to a mono client.
The dotNET service is hosted in a console application. The configuration is below. Make sure to use the webHttpBinding.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <!--Streaming over REST--> <service name = "FileService.ServiceImplementation.RESTService"> <host> <baseAddresses> <add baseAddress = "http://localhost:999/Files/REST"/> </baseAddresses> </host> <endpoint address = "" binding = "webHttpBinding" contract = "FileService.ServiceContract.IRESTService"> </service> </services> </system.serviceModel> </configuration>
REST makes use of the WebGet Attribute on the opartions in the ServiceContract. The UriTemplate maps the url to the service operation. Here the last and second last parts of the url are maped to parameters of the DownloadFile operation. The name of the part between the braces ({}) maps to the parameter with the same name. The result is a stream, more about that in the client code. I trust you can implement the operation yourself, just make sure to return a stream.
[ServiceContract] public interface IRESTService { [OperationContract] [WebGet(UriTemplate = "downloadfile/{name}/{id}")] Stream DownloadFile(string name, string id); }
In the client (on mono) make use of the HttpWebRequest object. Build the url with the knowledge of the interface UriTemplate and read the response stream which is the stream returned from the fileservice.
using System.Net; using System.IO; // ... var name = "myfile.txt"; var id = "12345"; // create the request url with the parameters inside the url var address = string.Format("http://localhost:999/Files/REST/downloadfile/{0}/{1}", name, id); // create the request object HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest; // call to the REST service using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { // Get the response stream using (var stream = response.GetResponseStream()) { // dosomething with the stream } // cleanup response.Close(); }
This solution uses default HTTP implementation and is supported on all platforms. Because the url is used for passing parameters the use of string paramaters is prefered. Complex types are not support, but could be passed in with the header of the request. These differences make REST less transparent but it is the price to pay if you need streaming on mono.