0

I'm stuck with an annoying problem.

There is a database containing images as byte arrays. I use the following method to get the images back from the byte arrays:

// byte[] ImageData contains the image loaded from the DB.

var stream = new MemoryStream(ImageData);
Image img = Image.FromStream(stream);
img.Save("D://Test/test.png", ImageFormat.Png);

When the Client requests an image from the server I run the above code on both server AND client side (with different filenames).

The thing is: when I'm on server side, this works wonderfully. File saves, and I can open and view the image in Windows Photo Viewer.

But when I get to client side, it seems like there have been some changes to this byte array, and Image throws an exception complaining about invalid parameters.

Also, I tried to save the byte array as it is with .png extension and then open it with Photo Viewer. It also fails.

What could possibly happen to my data when travelling through WCF, that causes the faulty byte array?

EDIT: Results of comparing files on server and client side.

Arrays look the same on both sides, EXCEPT on client side they miss the last few bytes. Even though the array on client side has actually LESS data, the file size says the client side image is BIGGER (by exactly 55 bytes) than it was on the server side.

The server is nothing fancy. Client calls DownloadImg in a BackgroundThread, but directly on the service reference like this:

var result = _service.DownloadImg(id);

Service interface:

[ServiceContract(Namespace="http://cannottellyou.com")]
public interface IImageService
{
    [OperationContract]
    DBImage DownloadImg(int id);
}

The Image object:

[DataContract(Namespace="http://cannottellyou.com")]
public class DBImage
{
    [DataMember]
    public virtual byte[] Data { get; set; }
}

The function that loads the image on server:

public class ImgService: IImageService
{
    public DBImage DownloadImg(int id)
    {
        var img = new DBImage();

        //That is where we get the byte array, and where I tested the image with the above code, and it works. I am sorry I cannot tell you more about this part...
        // img.Data holds the byte[] by now

        return img;
    }
}

The binding:

<binding name="BinBinding" messageEncoding="Mtom"
    closeTimeout="00:10:00"
    openTimeout="00:01:00"
    sendTimeout="00:05:00"
    receiveTimeout="00:10:00"
    maxReceivedMessageSize="67108864"
    maxBufferPoolSize="65536">
    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="2097152"
        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
    <security mode="None">
        <message  />
    </security>
</binding>
5
  • 2
    You have to post your WCF interface/methods, bindings as well as client call code for us to look at Commented Apr 3, 2012 at 13:09
  • Well, you seem very reluctant to tell us the most important parts. So what is DBImage ? If you don't want to reveal that, have you tried to return a simple ByteArray instead? Commented Apr 3, 2012 at 16:24
  • @MagnusJohansson: DBFile is 2 strings and a byte array :) Commented Apr 3, 2012 at 17:13
  • 1
    Dump the raw byte arrays to a file server side and client side and then diff them (eg with WinMerge). Commented Apr 3, 2012 at 17:26
  • @Ricibob: It looks like a standard amount of bytes is missing on the client side, regardless of the original size of the array. Commented Apr 4, 2012 at 13:12

3 Answers 3

1

It seems like this was caused by the Mtom encoding. We switched to Base64 and everything is fine now.

But still don't know exactly why...

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

Comments

0

I have no clue but you can try this :

  • You're returning DBImage, have you tried just returning byte[] Data?
  • Are you sure you're image isn't bigger than your bindingsetting?

1 Comment

Haven't tried the 1st yet, but I'm quite sure that this bug is not because of any size limitation, cause it happens with ALL images, bigger and smaller, and they ALLWAYS miss 55 bytes when they arrive.
0

Normally if the array is bigger than the limits set in the various binding parameter I would expect an exception not a truncated array and its weird that the bytes are missing regardless of the org image/array size. I think you must be doing some odd somewhere. But just to be sure Id try with read quota bumped up:

   <readerQuotas maxDepth="32"
        maxStringContentLength="10000000" maxArrayLength="10000000"
        maxBytesPerRead="10000000" maxNameTableCharCount="10000000" />

and buffers the same:

 maxBufferPoolSize="10000000" maxBufferSize="10000000" maxReceivedMessageSize="10000000">

but from your description I'm not sure this will help.

Comments

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.