3

I'm using Sql server file stream type to store large files in the backend. I'm trying to use WCf to stream the file across to the clients.

I'm able to get the handle to the file using SQLFileStream (API). I then try to return this stream. I have implemenetd data chunking on the client side to retrive the data from the stream.

I'm able to do it for regular filestream and memory stream. Also if i convert then sqlfilestream in to memorystream that also works. The only think that doesn't work is when I try to return sqlfilestream. What am I doing wrong.

I have tried both nettcpbinding with streaming enabled and http binding with MTOM encoding.

This is the error message am getting :


Socket connection was aborted. This could be caused by an error processing your mesage or a receive timeout being exceeded by the remote host, or an underlying network issue.. Local socket timneout was 00:09:59....

Here is my sample code

        RemoteFileInfo info = new RemoteFileInfo();
        info.FileName = "SampleXMLFileService.xml";

        string pathName = DataAccess.GetDataSnapshotPath("DataSnapshot1");

        SqlConnection connection = DataAccess.GetConnection();            

        SqlTransaction sqlTransaction = connection.BeginTransaction("SQLSileStreamingTrans");
        SqlCommand command = new SqlCommand();
        command.Connection = connection;
        command.Transaction = sqlTransaction;
        command.CommandText = "SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()";

        byte[] transcationContext = command.ExecuteScalar() as byte[];

        SqlFileStream stream = new SqlFileStream(pathName, transcationContext, FileAccess.Read);

// byte[] bytes = new byte[stream.Length]; // stream.Read(bytes, 0, (int) stream.Length);

// Stream reeturnStream = stream; // MemoryStream memoryStream = new MemoryStream(bytes);

        info.FileByteStream = stream;

        info.Length = info.FileByteStream.Length;

        connection.Close();

        return info;

    [MessageContract]
    public class RemoteFileInfo : IDisposable
    {
        [MessageHeader(MustUnderstand = true)]
        public string FileName;

        [MessageHeader(MustUnderstand = true)]
        public long Length;

        [MessageBodyMember(Order = 1)]
        public System.IO.Stream FileByteStream;

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

ANy help is appreciated

0

1 Answer 1

2

I've just solved this for my situation.

My WCF service is set to InstanceContextMode.PerCall.

When I request the stream, I have to leave the transaction/ connection open until the object is used by the client. It's done via the Dispose method of the service (if you implement IDisposable, WCF will automatically call Dispose for you).

Works like a charm for me, the stream is read on the client without issue.

Sign up to request clarification or add additional context in comments.

2 Comments

fixed my problem! just to be clear for anyone unsure, pull out all of your using statements which many WCF streaming examples use (to ensure correct disposal of objects) and dispose of them in the service Dispose function (implementing IDisposable.
This VB.Net example does what you need - petermeinl.wordpress.com/2012/02/20/…, easily converted to C# as I have, if anyone needs help just drop me a message/comment as I know how frustrating service errors can be to fix!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.