Murhaf Sousli Murhaf Sousli - 3 months ago 26
C# Question

return Image from OperationContract method (WCF service)

Im trying to get an Image from WCF service

i have an OperationContract function that returns an Image to the client,
but when i call it from client
i get this exception :

The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:00:59.9619978'.


Client :

private void btnNew_Click(object sender, EventArgs e)
{
picBox.Picture = client.GetScreenShot();
}


Service.cs :

public Image GetScreenShot()
{
Rectangle bounds = Screen.GetBounds(Point.Empty);
using (Bitmap bmp = new Bitmap(bounds.Width,bounds.Height))
{
using (Graphics g = Graphics.FromImage(bmp))
{
g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
}
using (MemoryStream ms = new MemoryStream())
{
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
return Image.FromStream(ms);
}
}
}


IScreenShot Interface :

[ServiceContract]
public interface IScreenShot
{
[OperationContract]
System.Drawing.Image GetScreenShot();
}


so why is that happening and how do i fix it ?

Answer

I've figured it out.

  • First use TransferMode.Streamed // or StreamedResponse depends on your need.
  • return the stream, and dont forget to set Stream.Postion = 0 so start reading the stream from the begining.

in the service :

    public Stream GetStream()
    {
        Rectangle bounds = Screen.GetBounds(Point.Empty);
        using (Bitmap bmp = new Bitmap(bounds.Width, bounds.Height))
        {
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
            }
            MemoryStream ms = new MemoryStream();
            bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
            ms.Position = 0;  //This's a very important
            return ms;
        }
    }

interface :

[ServiceContract]
public interface IScreenShot
{
    [OperationContract]
    Stream GetStream();
}

on the client side :

public partial class ScreenImage : Form
{
    ScreenShotClient client;
    public ScreenImage(string baseAddress)
    {
        InitializeComponent();
        NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
        binding.TransferMode = TransferMode.StreamedResponse;
        binding.MaxReceivedMessageSize = 1024 * 1024 * 2;
        client = new ScreenShotClient(binding, new EndpointAddress(baseAddress));
    }

    private void btnNew_Click(object sender, EventArgs e)
    {
        picBox.Image = Image.FromStream(client.GetStream());
    }
}
Comments