WCF开发框架形成之旅--个人图片信息的上传保存

一般在业务系统里面,除了存储个人的基本信息外,可能也都需要存储个人的一些图片信息,通常如肖像、名片、身份证等重要图片信息,而这些信息偏小为了方便管理,一般也是和个人基本信息一起放在数据库里面的。

本人在开发形成自己的Winform开发框架及WCF开发框架过程中,对这些进行了优化整理,现公布出来和大家一起讨论学习,希望给大家提供一个参考外,自己有进一步的提升。本文主要以WCF开发框架下的个人图片信息上传保存作为主题,介绍其中涉及到的一些知识点和操作,以及规避其中一些常见的问题。

1)首先,我们需要在数据库里面设置几个Image对象字段(我这里采用的是SqlServer数据库)。

 

2)我们需要先做好数据库存储底层的操作函数,把图片信息存储在不同的字段里面,由于这个操作类似,因此设置一个枚举来选择不同的字段存储,如下所示。

        /// <summary>
        
/// 根据图片枚举类型获取对应的字段名称
        
/// </summary>
        
/// <param name="imageType">图片枚举类型</param>
        
/// <returns></returns>
        private string GetFieldNameByImageType(UserImageType imageType)
        {
            string fieldName = "Portrait";
            switch (imageType)
            {
                case UserImageType.个人肖像:
                    fieldName = "Portrait";
                    break;
                case UserImageType.身份证照片1:
                    fieldName = "IDPhoto1";
                    break;
                case UserImageType.身份证照片2:
                    fieldName = "IDPhoto2";
                    break;
                case UserImageType.名片1:
                    fieldName = "BusinessCard1";
                    break;
                case UserImageType.名片2:
                    fieldName = "BusinessCard2";
                    break;
            }
            return fieldName;
        }


        /// <summary>
        
/// 更新个人相关图片数据
        
/// </summary>
        
/// <param name="imagetype">图片类型</param>
        
/// <param name="userId">用户ID</param>
        
/// <param name="imageBytes">图片字节数组</param>
        
/// <returns></returns>
        public bool UpdatePersonImageBytes(UserImageType imagetype, string userId, byte[] imageBytes)
        {
            string fieldName = GetFieldNameByImageType(imagetype);

            string sql = string.Format("update Users set {0}=@image where Id = '{1}' ", fieldName, userId);
            Database db = DatabaseFactory.CreateDatabase();
            DbCommand dbCommand = db.GetSqlStringCommand(sql);
            db.AddInParameter(dbCommand, "image", DbType.Binary, imageBytes);
            return db.ExecuteNonQuery(dbCommand) > 0;

        } 

3)以上是保存图片的操作,还需要做一个通用类型的图片下载操作,把用户图片信息保存在byte数组中,方便在客户端把字节转换为具体的文件字节。

         /// <summary>

        /// 根据个人图片枚举类型获取图片数据
        
/// </summary>
        
/// <param name="imagetype">图片枚举类型</param>
        
/// <returns></returns>
        public byte[] GetPersonImageBytes(UserImageType imagetype, string userId)
        {
            string fieldName = GetFieldNameByImageType(imagetype);

            string sql = string.Format("Select {0} from Users where Id = '{1}' ", fieldName, userId);
            Database db = DatabaseFactory.CreateDatabase();
            DbCommand dbCommand = db.GetSqlStringCommand(sql);

            byte[] imageBytes = null;
            using (IDataReader reader = db.ExecuteReader(dbCommand))
            {
                if (reader.Read())
                {
                    imageBytes = (reader.IsDBNull(reader.GetOrdinal(fieldName))) ? null : (byte[])reader[0];
                }
            }

            return imageBytes;
        }

 

4)然后设计一个图片上传显示的窗体,其中窗体的图片控件默认显示一个替代的图片,一个美观,二个也方便用户快速设置图片,如下所示。

 

其最终效果如下所示,除了可以展示图片外,双击可以预览图片的内容,便于用户放大缩小对图片细看。

 

5)其中实现图片上传的WCF客户端代码如下所示。

        private void btnSavePortrait_Click(object sender, EventArgs e)
        {
            if (picPortrait.Image != null)
            {
                new UserServiceClient().Using(client =>
                {
                    try
                    {
                        byte[] imageBytes = ImageHelper.ImageToBytes(this.picPortrait.Image);
                        bool sucess = client.UpdatePersonImageBytes(UserImageType.个人肖像,
                            Portal.gc.LoginInfo.Id, imageBytes);
                        MessageDxUtil.ShowTips(sucess ? "个人肖像 图片保存成功!" : "保存失败!");
                    }
                    catch (Exception ex)
                    {
                        MessageDxUtil.ShowError(ex.Message);
                        LogTextHelper.Error(ex);
                    }
                });
            }
       } 

 

 重置图片的代码如下所示。

private void ResetDefaultImage(UserImageType imageType)
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmPersonalInfo));
            switch (imageType)
            {
                case UserImageType.个人肖像:
                    this.picPortrait.EditValue = ((object)(resources.GetObject("picPortrait.EditValue")));
                    break;
                case UserImageType.身份证照片1:
                    this.picIDCard1.EditValue = ((object)(resources.GetObject("picIDCard1.EditValue")));
                    break;
                case UserImageType.身份证照片2:
                    this.picIDCard2.EditValue = ((object)(resources.GetObject("picIDCard2.EditValue")));
                    break;
                case UserImageType.名片1:
                    this.picCard1.EditValue = ((object)(resources.GetObject("picCard1.EditValue")));
                    break;
                case UserImageType.名片2:
                    this.picCard2.EditValue = ((object)(resources.GetObject("picCard2.EditValue")));
                    break;
            }
        } 


由于采用了枚举类型UserImageType来区分不同的图片信息,因此多种图片的上传、显示、重置操作,基本上都相同的,较好地实现了代码的重用。另外值得注意的是,WCF默认不支持大一点的图片上传,一般需要设置配置文件来实现图片数据的上传(一般图片还是有点大的),所以需要设置服务端和客户端的配置文件,如下所示。

服务端的Web.Config配置文件如下所示 

 

客户端配置如下所示。 

 

 

 

主要研究技术:代码生成工具、Visio二次开发、送水管理软件等共享软件开发
专注于Winform开发框架、WCF开发框架的研究及应用。
  转载请注明出处:
撰写人:伍华聪  http:
//www.iqidi.com 
    

posted on 2011-12-23 16:57 伍华聪 阅读(1919) 评论(12) 编辑 收藏

评论

#1楼  回复 引用 查看   

想学wcf,有好书推荐不
2011-12-23 17:48 | 浅晗若丶      

#2楼  回复 引用 查看   

@浅晗若丶
http://www.cnblogs.com/artech/
博客里都是,还出过书
2011-12-23 22:36 | Hi小鬼      

#3楼  回复 引用 查看   

我个人看法是WCF并不适合做流传输,虽然WCF可以通过一些手段来优化流传输时的性能,但是总的来说WCF做消息交换更加靠谱一些。
2011-12-23 22:37 | SnowDreamist      

#4楼  回复 引用 查看   

顶一个,伍哥好;
2011-12-24 09:18 | 南京.王清培      

#5楼[楼主]  回复 引用 查看   

引用南京.王清培:顶一个,伍哥好;

感谢支持
2011-12-24 09:52 | 伍华聪      

#6楼[楼主]  回复 引用 查看   

引用SnowDreamist:我个人看法是WCF并不适合做流传输,虽然WCF可以通过一些手段来优化流传输时的性能,但是总的来说WCF做消息交换更加靠谱一些。

一般处理都没什么问题的。
2011-12-24 09:52 | 伍华聪      

#7楼  回复 引用 查看   

@伍华聪

WCF来做一个是流的大小限制,而且最大的弊端是WCF需要缓存整个流到内存然后在写到磁盘或者其他地方,就是你的byte[]。传统的asp.net模式也有这个问题,asp.net的流传输模式可以直接把接收到的流写入文件,或者开启IIS的这个设置,不过我太清楚WCF和这个兼容不。
对于不大的小文件这么做也没什么问题,嘿嘿。
2011-12-24 12:21 | SnowDreamist      

#8楼  回复 引用 查看   

文件大了后,有些麻烦,我就遇到了文件大了不好用的情况。
2011-12-24 15:03 | 吉日嘎拉(杭州)      

#9楼  回复 引用 查看   

图片保存到数据库中?数据库会被撑很大的哦。我现在是把图片文件上传到服务器,数据库保存路径,客户端显示的时候,先由服务器端返回一个缩略图,如果双击图片看大图,再把原图下载来来显示。
2011-12-24 18:09 | 侯唯      

#10楼[楼主]  回复 引用 查看   

引用侯唯:图片保存到数据库中?数据库会被撑很大的哦。我现在是把图片文件上传到服务器,数据库保存路径,客户端显示的时候,先由服务器端返回一个缩略图,如果双击图片看大图,再把原图下载来来显示。


一般用户的小图像是可以放到数据库里面去的,这也是通用做法,大的如个人相片,则一般放到文件处理,数据库记录路径即可。
2011-12-25 14:14 | 伍华聪      

#11楼  回复 引用 查看   

谢谢分享
2011-12-27 11:42 | 烧点饭      

#12楼  回复 引用 查看   

make make
2012-02-15 14:29 | jiangsoft      

导航

<2011年12月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

公告

昵称:伍华聪
园龄:6年7个月
荣誉:推荐博客
粉丝:676
关注:23

搜索

 

常用链接

最新随笔

我的标签

随笔档案(202)

文章分类(14)

文章档案(15)

相册

我的好友

我的技术支持站点(http://www.iqidi.com)

积分与排名

  • 积分 - 629355
  • 排名 - 79

最新评论

阅读排行榜

评论排行榜

推荐排行榜