最近在学习WCF技术,开始看了《WCF技术剖析(卷1)》一书,暂不说看不看得懂,反正就是从头翻到尾,跳着跳着看,总算是“看完了”。因为以前一直是做Winform开发,对Web Service技术也是一片茫然,学习WCF真的是头痛头大,不过到目前总算是有所了解了,还不能说真的懂了。
下面说说我遇到的问题吧。服务端提供一个方法,返回一个图像(Image)。很简单是不是,那么下面开始编码:
服务端:
定义一个接口
[ServiceContract]publicinterfaceIMessage
{
[OperationContract]
Image GetImage();
}
实现接口
publicclassMessageService : IMessage
{publicImage GetImage()
{returnImage.FromFile(@"D:\资料\...\图像.png");
}
}
客户端:
代码
//按钮事件privatevoidbutton1_Click(objectsender, EventArgs e)
{
ChannelFactory_imFactory=newChannelFactory("imservice");
IMessage _messageService=_imFactory.CreateChannel();this.pictureBox1.Image=_messageService.GetImage();
_imFactory.Abort();
_imFactory.Close();
}
服务端和客户端配置文件省略,看似没有问题,那么下面运行一下客户端,看看实际效果。
这里发现客户端在调用GetImage方法时出错了。
是什么原因呢?Image不能被序列化吗?通过查找定义发现Image是这样的:
代码
//摘要://为源自 System.Drawing.Bitmap 和 System.Drawing.Imaging.Metafile 的类提供功能的抽象基类。[Serializable]
[ComVisible(true)]
[Editor("System.Drawing.Design.ImageEditor, System.Drawing.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",typeof(UITypeEditor))]
[ImmutableObject(true)]
[TypeConverter(typeof(ImageConverter))]publicabstractclassImage : MarshalByRefObject, ISerializable, ICloneable, IDisposable
{
。。。
}
很明显Image类含有SerializableAttribute特性,于是百思不得其解,这个问题苦恼了我很久!
在网上搜了很多次,也没找到相关的答案,后来找到了Artech,向他请教了这个问题,他很快给出了解决方法,真的很佩服他谢谢他。
你使用的真实类型是Bitmap,你可以试试下面两种解决方案:
1、将ServiceContract的返回值类型从Image换成Bitmap ;
2、通过System.ServiceModel.ServiceKnownTypeAttribute让Bitmap变成已知类型
经过将Image替换成Bitmap,果然客户端不再出现异常!问题解决了!