简体   繁体   English

从 OperationContract 方法(WCF 服务)返回图像

[英]Returning an Image from OperationContract method (WCF service)

I'm trying to get an Image from a WCF service.我正在尝试从 WCF 服务获取Image

I have an OperationContract function that returns an Image to the client, but when I call it from the client, I get this exception:我有一个OperationContract函数,可以将Image返回给客户端,但是当我从客户端调用它时,出现以下异常:

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'.本地套接字超时为“00:00:59.9619978”。

Client:客户:

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

Service.cs:服务.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: IScreenShot界面:

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

So why is this happening and how do I fix it?那么为什么会发生这种情况,我该如何解决呢?

I've figured it out.我已经想通了。

  • First use TransferMode.Streamed or StreamedResponse (depends on your need).首先使用TransferMode.StreamedStreamedResponse (取决于您的需要)。
  • Return the stream, and don't forget to set Stream.Postion = 0 so you start reading the stream from the beginning.返回流,不要忘记设置Stream.Postion = 0以便从头开始读取流。

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 is 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());
    }
}

You can use Stream to return large data/Images.您可以使用 Stream 返回大数据/图像。

Sample Example(returning Image as Stream) from MSDN来自 MSDN 的示例示例(将图像作为流返回)

You will need to define something that is serializable.您将需要定义可序列化的内容。 System.Drawing.Image is, but not in the context of WCF (using DataContractSerializer ) by default. System.Drawing.Image是,但不在 WCF 的上下文中(使用DataContractSerializer )默认情况下。 That could range from returning the raw bytes as an array, or serialization to a string (base64, JSON) or implementing a DataContract that is serializable and can carry the data with it.这可能包括将原始字节作为数组返回,或序列化为字符串(base64、JSON)或实现可序列化并可以携带数据的DataContract

As others have said, WCF supports streaming, but that's not the crux of the issue here.正如其他人所说,WCF 支持流,但这不是问题的关键。 Depending on the size of the data you might wish to do this, and doing so will reduce the problem in itself since you would be streaming bytes (from an evident, top-level view).根据您可能希望这样做的数据大小,这样做会减少问题本身,因为您将流式传输字节(从明显的顶级视图)。

You could also take a look at this answer to help you get the at the actual exception details, like a full stacktrace instead of just the fault info.您还可以查看此答案以帮助您了解实际的异常详细信息,例如完整的堆栈跟踪,而不仅仅是错误信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM