views:

39

answers:

2

I have been creating a new service to download large file to client. I want to host the service in a Windows Service. In service I am writing :

 public class FileTransferService : IFileTransferService
    {
        private string ConfigPath
        {
            get
            {
                return ConfigurationSettings.AppSettings["DownloadPath"];
            }
        }
        private FileStream GetFileStream(string file)
        {

            string filePath = Path.Combine(this.ConfigPath, file);
            FileInfo fileInfo = new FileInfo(filePath);

            if (!fileInfo.Exists)
                throw new FileNotFoundException("File not found", file);

            return new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
        }

        public RemoteFileInfo DownloadFile(DownloadRequest request)
        {
            FileStream stream = this.GetFileStream(request.FileName);

            RemoteFileInfo result = new RemoteFileInfo();
            result.FileName = request.FileName;
            result.Length = stream.Length;
            result.FileByteStream = stream;
            return result;
        }
    }

The Interface looks like :

 [ServiceContract]
    public interface IFileTransferService
    {
        [OperationContract]
        RemoteFileInfo DownloadFile(DownloadRequest request);
    }
    [DataContract]
    public class DownloadRequest
    {
        [DataMember]
        public string FileName;
    }

    [DataContract]
    public class RemoteFileInfo : IDisposable
    {
        [DataMember]
        public string FileName;

        [DataMember]
        public long Length;

        [DataMember]
        public System.IO.Stream FileByteStream;

        public void Dispose()
        {
            if (FileByteStream != null)
            {
                FileByteStream.Close();
                FileByteStream = null;
            }
        }
    }

When I am calling the service it says "Underlying connection was closed." You can get the implementation http://cid-bafa39a62a57009c.office.live.com/self.aspx/.Public/MicaUpdaterService.zip Please help me.

+1  A: 

I have found very nice code in your service:

try
{
  host.Open();
}
catch {}

This is one of the worst antipatterns! Immediately replace this code with correct error handling and logging.

I didn't test your service but simply by looking to config and to your code I suggested that it will never work because it doesn't meat requirements for streaming over HTTP. When you want to stream over HTTP method must return only single body member which is of type Stream. Your method returns data contract instead. Use this version:

[ServiceContract]     
public interface IFileTransferService     
{     
    [OperationContract]     
    DownloadFileResponse DownloadFile(DownloadFileRequest request);     
}     

[MessageContract]     
public class DownloadFileRequest     
{     
    [MessageBodyMember]     
    public string FileName;     
}     

[MessageContract]     
public class DownloadFileResponse    
{     
    [MessageHeader]     
    public string FileName;     

    [MessageHeader]     
    public long Length;     

    [MessageBodyMember]     
    public System.IO.Stream FileByteStream;         
} 

Do not close the stream on the service. It is client's responsibility to close the stream.

Ladislav Mrnka
Ohh thank you for your comment. I am trying this.
abhishek
Whohoo.. It worked. Just another question, Can you tell me how to increase the size of message. It tells me to increase MaxReceivedMessageSize.
abhishek
You must set maxReceiveMessageSize on the client.
Ladislav Mrnka
Wow. I have just changed the transfermode in client to streamed and it worked magically. transferMode="Streamed"Thank you so much for your help. Cheers.
abhishek
A: 

Look at this article. Is it what you are looking for?

Oleg