C#中使用FileUpload上传图片到SQL数据库中以image类型存储并使用Image控件显示注意事项

当我们需要以数据流存储图片到数据库中(而不是文件路径),需要考虑很多因素,不同的环境决定了采取不同方法。

1.将图片存入数据库。首先,当我们决定使用FileUpload上传图片,需要考虑,FileUpload的功能主要是在客户端选取图片,然后使用FileUpload的SaveAs方法将选取的图片的地址保存到服务器端保存,因为我们使用的数据流存储图片,所以没有必要将图片保存到服务器端。

其次,FileUpload没有像OpenDialog的.Filter方法过滤图片的格式,即实现打开对话框,只能选择图片格式的文件的形式。所以这里我们需要自己写代码过滤文件的格式。

下面就是上传图片的主要代码:

//上传图片

if(fupContractPhoto.PostedFile.ContentLength<500000)//限制文件大小为100000为100K

{

string fileFullName = this.fupContractPhoto.PostedFile.FileName;
 //文件完整名称

string fileName = fileFullName.Substring(fileFullName.LastIndexOf("\\") + 1);   //文件名

string type = fileName.Substring(fileName.LastIndexOf(".") + 1);    //文件类型

if (type.ToLower() == "bmp" || type.ToLower() == "jpg" || type.ToLower() == "gif" || type.ToLower() == "png")

{

string fileFullPath=Server.MapPath("~/upload")+"\\"+fileName;

this.fupContractPhoto.SaveAs(fileFullPath);

//将文件转化为数据流

FileStream fs = new FileStream(fileFullPath, FileMode.Open);    //文件流

byte[] imageBytes=new byte[fs.Length];  //设定字节流数组大小

BinaryReader br = new BinaryReader(fs);    
//读字节对象

imageBytes = br.ReadBytes(Convert.ToInt32(fs.Length));  //将字节流读入字节数组中

//将字节流对象赋值给Project对象

project.ContractPhoto = imageBytes;

}

}

需要说明的是:Asp.net代码页面里使用的是对象类型的某个字段存储图片转化成的Byte[ ]字节数组,这里使用的Project对象的一个实例project的属性ContractPhoto。数据库中使用的是Image类型的字段存储将要上传的图片。

下面就是和数据库交互的语句:

首先因为这里将图片转换成字节流并用字节数组存储,有人会想直接使用insert语句插入到数据中对应的字段可不可以,答案是不可以的。如这样的形式:string sql=string.Format("insert into Project(ContractPhoto) values(‘{0}‘)",project.ContractPhoto);通过断点调试可以看到存入数据库中的是System.Drawing而不是字节流数据。那么我们通过Convert.toBase64String将字节流转化成二进制字符串可以吗?答案是可以的,但是当显示图片会出现无法显示的情况。那么我们如何将数据插入到数据库中呢?这个问题纠结了很长时间,最后通过Command类将需要插入数据库中的数据以参数的形式插入到数据库,这种方法是可行的。如这样的形式:string
sql="insert into Project(ContractPhoto) values(@ContractPhoto)";然后使用SqlParameter类组织参数数组。由于SQLHelper类是微软编写的Ado.net类用户数据库交互提供方便这里就简洁点通过这个类来具体实现。

下面就是实现插入自己数组数据到数据库中的代码:

 public int AuditProject(Project project)

{

//SQL语句

string sql = "update Project set ProjectStatus=2,[email protected],[email protected],[email protected] where [email protected]";

//组织参数

SqlParameter[ ] objParams = new SqlParameter[4];

objParams[0] = new SqlParameter("@ContractNO",project.ContractNO);  //合同编号

objParams[1] = new SqlParameter("@ContractAmount", project.ContractAmount); //合同金额

objParams[2] = new SqlParameter("@ContractPhoto", project.ContractPhoto);   //合同照片

objParams[3] = new SqlParameter("@ProjectID", project.ProjectID);   //项目编号

return SqlHelper.ExecuteNonQuery(SqlHelper.ConnString, CommandType.Text, sql, objParams);

}

这里使用的是我的项目中部分代码用户展示,可以借鉴其中的方法实现具体功能。主要加了一个参数类,通过参数传入,最后通过Cammand类实现的(因为SQLHELPER类已经封装,这里看不到具体实现)。

2.下面就是数据库中图片显示到Asp.net页面中。首先我们需要考虑使用什么控件显示,并注意控件的特性。一般使用Image服务器控件显示图片,问题来了如何显示呢。因为Image控件使用的是给Image的ImageURL属性赋图片路径值显示,而我们存储图片是以二进制字节流形式存储图片而不是图片的路径。我们只能通过其他形式转化来。具体实现:在我们的页面添加一个ContractPhoto.aspx(名字可以随便写),这个页面主要实现功能的不用于显示图片的,主要利用Response的一个读二进制字节流的方法,然后将将图片显示在Image控件中的形式。具体做法:<asp:Image
ID="imgContractPhoto" runat="server" Height="360px" Width="721px" />

在服务器后台代码中这样写: 

imgContractPhoto.ImageUrl = "ContractPhoto.aspx?ProjectID=" + project.ProjectID; //图片

用于指向图片页面并传递相应参数用于一个控件在不同条件下显示不同图片的功能。

下面就是ContractPhoto.aspx后台代码的实现:

 protected void Page_Load(object sender, EventArgs e)

{

//定义ProjectID获取QueryString中获取的ProjectID

int projectID = Convert.ToInt32(Request.QueryString["ProjectID"]);

//通过projectID获取Project信息

Project project = projectManager.GetProjectByProjectID(projectID);

byte[ ] b_ContractPhotoImg =project.ContractPhoto;

if (b_ContractPhotoImg.Length > 0)

      {

    Response.Clear();

    Response.ContentType = "image/jpeg";

Response.OutputStream.Write(b_ContractPhotoImg, 0, b_ContractPhotoImg.Length);

    Response.End();

  }

}

由于数据中取出数据给project.ContractPhoto的过程被我省略了,这里贴一个短小代码显示取字节流的过程。

 project.ContractPhoto = (byte[ ])(reader["ContractPhoto"]);    //合同图片

reader是SqlDataAdapter对象。

这样就可以显示数据库中存储的字节流数据了。

3.还有个很重要的问题需要交代:大家都以为只要我们的程序发布到IIS上就可以实现功能了,确实是这样的在本地IIS上发布网页,实现功能没有任何问题,但是发布到远端的服务器上就会提示文件没有权限或者文件地址不存在问题。这个问题纠结了很长时间终于解决了。问题的根源主要有两个:1.本地的文件上传到服务器上,我们使用FileUpload上传时,会显示文件地址,但这个地址是我们本地文件中的地址,当我们把网页发布到服器上的IIS时,服务器却找不到本地计算机所存地址,就会提示文件不存在问题。如果是本地,并在本地发布IIS本地的IIS能直接访问本地路径,当然没有任何问题。问题来,怎样实现功能呢???2.我们可以“曲线救国”,直接存不行,我们可以使用FileUpload的SaveAs方法
先在服务上建立一个upload文件夹,然后使用SaveAs方法将本地的文件存放到upload文件夹里。当我们需要访问文件时直接使用Server.Mappath方法获取项目所在地址并找到upload中文件。如果使用完不需要可以使用File.Delete(string path)方法删除服务器端文件。这么说有点抽象贴一段代码就很明显了。

代码如下:

   
string fileFullPath=Server.MapPath("~/upload")+"\\"+fileName;

this.fupContractPhoto.SaveAs(fileFullPath);

//将文件转化为数据流

FileStream fs = new FileStream(fileFullPath, FileMode.Open);    //文件流

byte[] imageBytes=new byte[fs.Length];  //设定字节流数组大小

BinaryReader br = new BinaryReader(fs);     //读字节对象

imageBytes = br.ReadBytes(Convert.ToInt32(fs.Length));  //将字节流读入字节数组中

至此所有的功能点都讲完了,大家可以根据自己的项目需要汲取其中一两点。因为看了网上讲的鱼龙混杂,所以在这完整的表述出来,希望能给大家帮助!

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-17 07:21:32

C#中使用FileUpload上传图片到SQL数据库中以image类型存储并使用Image控件显示注意事项的相关文章

C#将SQL数据库中数据导入Excel中,并将Excel中反导入SQL数据库中

实际的开发中,我们会经常遇到数据的转化的需要,将Excel中的数据转入到SQL中,或将SQL在数据库表中的数据导入到Excel中.代码如下: Code using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windo

sql数据库中查询第几条到第几条的数据

通用方法: select top 500 * from (select top 1000 * from UserSearchDatas order by ID) a order by ID desc sql数据库中查询第几条到第几条的数据,布布扣,bubuko.com

SQL数据库中的主键与外键的介绍

一.什么是主键.外键: 关系型数据库中的一条记录中有若干个属性,若其中某一个属性组(注意是组)能唯一标识一条记录,该属性组就可以成为一个主键比如 : 学生表(学号,姓名,性别,班级) 其中每个学生的学号是唯一的,学号就是一个主键 用户表(用户名.密码.登录级别) 其中用户名是唯一的, 用户名就是一个主键 上机记录表(卡号,学号,姓名.序列号) 上机记录表中单一一个属性无法唯一标识一条记录,学号和姓名的组合才可以唯一标识一条记录,所以 学号和姓名的属性组是一个主键 上机记录表中的序列号不是成绩表的

转:SQL数据库中临时表、临时变量和WITH AS关键词创建“临时表”的区别

原文链接:https://www.cnblogs.com/zhaowei303/articles/4204805.html SQL数据库中数据处理时,有时候需要建立临时表,将查询后的结果集放到临时表中,然后在针对这个数据进行操作. 创建"临时表"(逻辑上的临时表,可能不一定是数据库的)的方法有一下几种: 1.with tempTableName as方法(05之后出现): with temptable as 其实并没有建立临时表,只是子查询部分(subquery factoring),

关于在java中向带有IN的SQL语句中传参数的问题

今天遇到俩个问题: 1.在使用表格模型的时候,从数据库查询出来的数据赋值到Jtable的时候永远只显示最后一天记录,前面的都被覆盖了.一直在究其原因,未果,遂择其道而行之(第二个问题). 2.为了解决上面的问题,我将SQL语句的条件换成IN,目的想把所有参数一并传过去,查询所有记录后在一并显示到Jtable上,实验证明我的做法是对的.但是,一直没有搞懂IN(?)这个问号应该如何传值. SQL : String sql = " select sxh,grbm,xm,yybm,fyze,qzfbf,

sql 数据库中只靠一个数据,查询到所在表和列名

有时候我们想通过一个值知道这个值来自数据库的哪个表以及哪个字段,在网上搜了一下,找到一个比较好的方法,通过一个存储过程实现的.只需要传入一个想要查找的值,即可查询出这个值所在的表和字段名. 前提是要将这个存储过程放在所查询的数据库. 注:1步骤是创建存储过程,可以在任何一个数据库中使用,2步骤是调用它来查找数据库中所有牵扯到的列以及对应的表. 只需要一个数据 真是非常方便 一.首先 点击新建查询 ,左上角选择到自己的数据库,然后把下面这段复制进去  然后运行 CREATE PROCEDURE [

DataTable批量存数SQL数据库中

1 #region 使用SqlBulkCopy将DataTable中的数据批量插入数据库中 2 /// <summary> 3 /// 使用SqlBulkCopy将DataTable中的数据批量插入数据库中 4 /// </summary> 5 /// <param name="strTableName">数据库中对应的表名</param> 6 /// <param name="dtData">数据集<

Session如何保存在sql数据库中

aspnet中,session默认以inproc模式存储,也就是保存在iis进程中,这样有个优点就是效率高,但不利于为本负载均衡扩展.可以把session信息保存在SQL Server中,据说,该种方式比起inproc性能损失为10%-20%.如何实现呢,主要分两步介绍: 1.初始化SQL Server中的状态数据库 ASP.NET SQL Server 提供注册工具Aspnet_regsql.exe,用于创建供 ASP.NET 中的 SQL Server 提供程序使用的 Microsoft S

SQL中的where条件,在数据库中提取与应用浅析

来源:深入MySQL内核 1        问题描述 一条SQL,在数据库中是如何执行的呢?相信很多人都会对这个问题比较感兴趣.当然,要完整描述一条SQL在数据库中的生命周期,这是一个非常巨大的问题,涵盖了SQL的词法解析.语法解析.权限检查.查询优化.SQL执行等一系列的步骤,简短的篇幅是绝对无能为力的.因此,本文挑选了其中的部分内容,也是我一直都想写的一个内容,做重点介绍: 给定一条SQL,如何提取其中的where条件?where条件中的每个子条件,在SQL执行的过程中有分别起着什么样的作用