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客户端代码如下所示。
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);
}
});
}
}
重置图片的代码如下所示。
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配置文件如下所示
客户端配置如下所示。