首先引入这个问题,一个注册会员的网站,一般会要求用户上传头像。这里我们就是针对上传头像这一模块,做相应的操作。
当用户把头像上传到注册页面后,注册页面要显示这个头像,还能在此会员下次登录这个网站时,显示出会员的头像,那么我们头像的信息应该也与会员别的信息一样被存入到数据库中,即数据库里有一个字段是关于头像的。至于这个字段到底应该存什么,可以分为两种情况:存入头像的链接地址,即imageURL;或头像转为二进制流后存入。本例中我们的数据库从简,只设置两个字段(会员编号cBh,会员头像bPhoto),头像是以二进制流存入数据库的。
先来看看我们页面上关于头像上传的部分,如下图所示:
与此部分对应的前台HTML页面代码为:
1 <td align="center" class="style1"> 2 <asp:Image ID="photo" runat="server" Width="125px" Height="120px" ImageAlign="Middle" 3 BorderWidth="1px" ImageUrl="~/images/photo.jpg" /> 4 5 </td> 6 <td class="style5"> 7 <table id="tab"> 8 <tr> 9 <td class="style6" align="center"> 10 <label>请选择要上传的照片<br /> 11 支持格式.jpg与.bmp!</label></td> 12 </tr> 13 <tr> 14 <td class="style6"> 15 <asp:FileUpload runat="server" ID="choicePhoto" Width="217px"/> 16 </td> 17 </tr> 18 <tr> 19 <td class="style6" align="center"> 20 21 <asp:Button runat="server" Text="上传照片" Width="119px" ID="importPhoto" 22 onclick="importPhoto_Click" /> 23 </td> 24 </tr> 25 </table> 26 </td>
用户对应的操作为:点击浏览,然后选择好要上传的图片后,点击上传照片。关于浏览按钮,下节将做详细介绍。
上传照片按钮的代码为:
1 protected void importPhoto_Click(object sender, EventArgs e) 2 { 3 this.funImportPhoto(); 4 } 5 private void funImportPhoto() 6 { 7 string filePath = this.choicePhoto.PostedFile.FileName.ToString().Trim();//文件路径 8 string fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);//文件名 9 string fileEx = fileName.Substring(fileName.LastIndexOf(".") + 1);//文件后缀名 10 string relativeName = "~/images/";//相对 11 string absoluteName = Server.MapPath(relativeName);//绝对,这里需要注意,relativeName是必须存在的,即有这个目录 12 if (fileEx == "jpg" || fileEx == "bmp") 13 { 14 string newFileName = Guid.NewGuid().ToString();//生成新的文件名,保证唯一性 15 string newFilePath = absoluteName + newFileName + "." + fileEx; 16 this.choicePhoto.PostedFile.SaveAs(newFilePath);//将文件存储到服务器上 17 this.photo.ImageUrl = relativeName + newFileName + "." + fileEx; 18 } 19 else 20 { 21 ShowMessage("请选择正确的照片格式!", ""); 22 } 23 24 }
上述代码里面的 string filePath = this.choicePhoto.PostedFile.FileName.ToString().Trim();这一行需要做详细的解释。这一句是获得图片路径的方法(不同的浏览器有不同的值),目前我接触到的IE6和FireFox得到的结果就不一样。IE6获得的是图片的绝对路径,而FireFox只能得到图片的名字而已。所以为了通用性,我们暂且忽略这一行得到的到底是名字还是路径,我们都要通过上述的代码,先从此结果里截取出图片的名字(上面funImportPhoto()函数里的的第二行)。然后为图片设置一个虚拟路径先暂存图片,然后再将图片的暂存相对路径付给image控件的imageURL。
至此当你点击上传图片运行完上述代码后,你会发现你的界面变成:
这个显示类似于预览的功能,只是让你看到你上传的头像在界面中显示的样子,这里还没有将图片保存进数据库中。
正常操作下,当会员填好自己的一切信息后,点击保存才会进行信息的提交。提交的数据才会被存入到数据库中,在数据库里bPhoto字段的类型为:
保存按钮的函数为:
protected void save_Click(object sender, EventArgs e) { People pe = new People() ; pe.cBh = this.txtBh.Text; pe.bPhoto = this.storePhoto();//从控件读取图片信息的函数 }
上述的storePhoto()为从image控件读取到图片信息,并将其转成二进制流后,赋给会员People类的对象pe的bPhoto属性:
1 private Byte[] storePhoto() 2 { 3 string pictureURL = this.photo.ImageUrl; 4 string picturePath = Server.MapPath(pictureURL);//绝对路径 5 FileStream fs = new FileStream(picturePath, FileMode.Open, FileAccess.Read); 6 BinaryReader br = new BinaryReader(fs); 7 byte[] bytes = br.ReadBytes((int)fs.Length); 8 br.Close(); 9 fs.Close(); 10 return bytes; 11 }
然后就是将对象pe的各属性存入到数据库中:
1 StringBuilder strSql = new StringBuilder(); 2 strSql.Append("insert into people("); 3 strSql.Append("cBh,bPhoto )"); 4 strSql.Append(" values ("); strSql.Append("@cBh,@bPhoto)"); 5 SqlParameter[] parameters = 6 { 7 new SqlParameter("@cBh", SqlDbType.NVarChar,20), 8 new 9 SqlParameter("@bPhoto",SqlDbType.VarBinary,1000000)//2013-04-24 10 }; 11 parameters[0].Value = pe.cBh; 12 parameters[1].Value = pe.BPhoto; 13 object obj = DbHelperSQL.GetSingle(strSql.ToString(), parameters);
1 public static object GetSingle(string SQLString, params SqlParameter[] cmdParms) 2 { 3 using (SqlConnection connection = new SqlConnection(connectionString)) 4 { 5 using (SqlCommand cmd = new SqlCommand()) 6 { 7 try 8 { 9 PrepareCommand(cmd, connection, null, SQLString, cmdParms); 10 object obj = cmd.ExecuteScalar(); 11 cmd.Parameters.Clear(); 12 if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))) 13 { 14 return null; 15 } 16 else 17 { 18 return obj; 19 } 20 } 21 catch (System.Data.SqlClient.SqlException e) 22 { 23 throw e; 24 } 25 finally 26 { 27 cmd.Dispose(); 28 connection.Close(); 29 } 30 } 31 }
以上便是从image控件中读取到图片然后将信息转化为二进制流后存入数据库的操作。
接下来我们思考从数据库中读取到图片后,将图片显示到image控件里,可以认为是上述操作的一个逆操作。
先是用select语句从数据库中取得数据:
1 StringBuilder strSql = new StringBuilder(); 2 strSql.Append("select cBh ,bPhoto from people "); 3 strSql.Append(" where cBh=@cBh "); 4 SqlParameter[] parameters = 5 { 6 new SqlParameter("@cBh", SqlDbType.NVarChar,20), 7 }; 8 parameters[0].Value =pe.cBh ; 9 People pe = new People(); 10 DataSet ds = DbHelperSQL.Query(strSql.ToString(), parameters);//这个函数要自己编写,即将查询数据存入到dataset中 11 if (ds.Tables[0].Rows.Count > 0) 12 { 13 pe.cBh = ds.Tables[0].Rows[0]["cBh"].ToString(); 14 if (ds.Tables[0].Rows[0]["bPhoto"].ToString() != "") 15 { 16 pe.BPhoto = (byte[])ds.Tables[0].Rows[0]["bPhoto"];//// 17 } 18 else 19 pe.BPhoto=new byte[0]; 20 return pe; 21 } 22 else 23 { 24 return null; 25 }
至此,数据已经读出来了,接下来就是显示了,你会发现这完全就是从image读取这个步骤的一个逆操作,部分代码如下:
1 if (pe.BPhoto.Length<1)//如果此人没有上传头像则头像为系统默认头像 2 { 3 this.photo.ImageUrl = "~/images/photo.jpg"; 4 } 5 else 6 { 7 byte[] picture = uworker.BPhoto; 8 string strRotePath = "~/images"; 9 string strName = Guid.NewGuid().ToString(); 10 string strPath = strRotePath + "/" + strName + ".jpg"; 11 string strAbsolutePath = Server.MapPath(strPath); 12 FileStream fs = new FileStream(strAbsolutePath, FileMode.OpenOrCreate, FileAccess.Write); 13 BinaryWriter bw = new BinaryWriter(fs); 14 bw.Write(picture); 15 bw.Flush(); 16 bw.Close(); 17 fs.Close(); 18 this.photo.ImageUrl = strPath; 19 }
当然其实更好的方法是将图片的URL地址存入数据库,以上的操作中只需要将自动产生的路径赋给相应控件就行了,这里就不做详细介绍。
好了,以上就是全部的操作了。希望能帮到在读的你。