在很多情况下,我们需要把图片保存到数据库中。在某些应用程序中,存在一些敏感信息不能被存储到文件系统中,因为存储在文件系统上的任何图片都很容易被用户非法获得。
本文将讨论在ASP.NET中怎样把图片保存到SQL SERVER数据库中。
在本文中我们将了解到以下几方面的内容:
l 上载图片文件的要求
l 使用Strem对象
l 获得上载图片大小和类型
l 如何使用InputStream方法?
上载图片文件的要求
在开始上载前我们需要作两件重要的事情
#Form标记的enctype属性需要被设置为如下形式:
enctype="multipart/form-data"
#提供一个让用户选择图片文件的Html控件:
<input type=file>
#还要引用System.IO命名空间来处理Strem对象
上述的三项都要应用到aspx页中。在SQL SERVER中还有以下的一些要求:
#一个至少有一个字段类型为Image的表
#另外有一个用来存储图片类型的Varchar类型的字段就更好了
那么,我们有了一个有Image字段类型的数据表和一个<input type=file>(HTML文件控件)。我们还需要一个提交按钮,当用户选择好图片后可以点击它。在按钮的OnClick事件中我们要获得图片文件的内容并最终把它插入到数据表中。让我们来看看按钮的OnClick事件,它读取图片并把图片插入到数据表中。
提交按钮的OnClick事件代码
Dim intImageSize As Int64
Dim strImageType As String
Dim ImageStream As Stream
' Gets the Size of the Image
intImageSize = PersonImage.PostedFile.ContentLength
' Gets the Image Type
strImageType = PersonImage.PostedFile.ContentType
' Reads the Image
ImageStream = PersonImage.PostedFile.InputStream
Dim ImageContent(intImageSize) As Byte
Dim intStatus As Integer
intStatus = ImageStream.Read(ImageContent, 0, intImageSize)
' Create Instance of Connection and Command Object
Dim myConnection As New SqlConnection(ConfigurationSettings.AppSettings("ConnectionString"))
Dim myCommand As New SqlCommand("sp_person_isp", myConnection)
' Mark the Command as a SPROC
myCommand.CommandType = CommandType.StoredProcedure
' Add Parameters to SPROC
Dim prmPersonImage As New SqlParameter("@PersonImage", SqlDbType.Image)
prmPersonImage.Value = ImageContent
myCommand.Parameters.Add(prmPersonImage)
Dim prmPersonImageType As New SqlParameter("@PersonImageType", SqlDbType.VarChar, 255)
prmPersonImageType.Value = strImageType
myCommand.Parameters.Add(prmPersonImageType)
Try
myConnection.Open()
myCommand.ExecuteNonQuery()
myConnection.Close()
Response.Write("New person successfully added!")
Catch SQLexc As SqlException
Response.Write("Insert Failed. Error Details are: " & SQLexc.ToString())
End Try它是如何工作的?
对象PersonImage 是HTMLInputFile 控件。首先我们要获得被插入图片的大小,通过如下方法实现:
intImageSize = PersonImage.PostedFile.ContentLength
接着要通过ContenType属性获得图片类型。最后最重要的是要获得图片文件流,通过如下方法实现:
ImageStream = PersonImage.PostedFile.InputStream
我们有一个byte数组ImageContent,准备用来保存图片内容。整个图片通过Stream对象的Read方法读取,这个方法有三个参数,即:
#被复制的图片内容的目标位置
#读的开始位置
#需要被读的子节数
读声明如下:
intStatus = ImageStream.Read(ImageContent, 0, intImageSize)
现在,我们读取了整个图片内容。接着我们需要把图片内容插入SQL数据表中,我们将用用一个存储过程把图片类型和图片插入SQL数据表。如果你看过上面的代码清单,你就知道我们把数据类型设置为SqlDbType.Image.就这样,我们成功地把图片保存到了SQL SERVER数据库。
例子的输出样例

图:将图片保存到sql server 数据库
测试下面的代码
代码下载
总结
通常,SQL 语句和存储过程包括运行时计算的参数。使用参数编写的 SQL 语句称作参数化 SQL 语句。
使用 SqlDataSource 控件时,可以指定使用参数的 SQL 查询和语句。通过根据运行时计算的值读写数据库信息,这有助于提升数据绑定环境的灵活性。可以从各种源获取参数值。这些源包括 ASP.NET 应用程序变量、用户标识和用户选择的值。可以使用参数执行下列操作:提供用于数据检索的搜索条件;提供要在数据存储区中插入、更新或删除的值;提供用于排序、分页和筛选的值。
同所有的数据源控件一样,SqlDataSource 控件在运行时接受输入参数,并在参数集合中对参数进行管理。每一项数据操作都有一个相关的参数集合。对于选择操作,可以使用 SelectParameters 集合;对于更新操作,可以使用 UpdateParameters 集合,依此类推。
可以为每个参数指定名称、类型、方向和默认值。对于从特定对象(例如,控件、会话变量或用户配置文件)获取值的参数,需要设置其他属性。例如,ControlParameter 要求设置 ControlID 以标识要从中获取参数值的控件,以及设置 PropertyName 属性以指定包含参数值的属性。有关更多信息,请参见对数据源控件使用参数。
另外,SqlDataSource 控件将基于支持自动更新、插入和删除操作的数据绑定控件(例如 GridView 或 FormView 控件)所传递的值自动创建参数。有关更多信息,请参见数据源控件如何为数据绑定字段创建参数。
使用 SqlDataSource 控件时,可以将该控件的命令属性设置为参数化 SQL 语句或存储过程的名称。如果指定命令的存储过程,必须将该命令的命令类型指定为 StoredProcedure。
SqlDataSource 控件可以将 ParameterPrefix 属性的值添加到所有参数名称的开头。(默认的前缀为“@”。)
如果 GridView 控件等数据绑定控件绑定到 SqlDataSource 控件,在执行更新或删除操作期间,该数据绑定控件会同时将当前记录值和原始记录值传递到 SqlDataSource 控件。当前值传递到 Values 字典中。原始值传递到 Keys 或 OldValues 字典中。对于给定的数据操作,这些字典的内容将会追加到基础 DbCommand 对象的 Parameters 集合中。
在 SqlDataSource 控件的 SQL 命令中,使用命名约定使参数占位符与传递到该命令的原来的值相匹配。通过设置 SqlDataSource 控件的 OldValuesParameterFormatString 属性,可以建立该占位符名称的格式。将 OldValuesParameterFormatString 属性设置为一个字符串。该字符串包含的“{0}”是该字段名称的占位符。例如,如果将 OldValuesParameterFormatString 属性设置为“old_{0}”,原始值参数的名称将会解析为前缀为“@old_”的字段名称。考虑对名为 LastModifiedDate 的字段执行更新操作。该字段的当前值传递到 Values 字典中,而该字段的原始值传递到 OldValues 字典中。此时,将会创建名为 @LastModifiedDate 参数,用来传递当前值,同时会创建名为 @old_LastModifiedDate 参数,用来传递原始值。此后,可以将这两个参数都包括在 SQL 语句中,以便区别该字段的当前值和原始值,如以下示例所示:
UPDATE Table1 SET LastModifiedDate = @LastModifiedDate WHERE Key = @Key AND LastModifiedDate = @old_LastModifiedDate
执行开放式并发检查或使用可以修改主键的数据源时,必须可以分隔命令中的当前值和原始值。
有关数据绑定控件传递的字典的更多信息,请参见数据源控件如何为数据绑定字段创建参数。
默认情况下,SqlDataSource 控件通过 System.Data.SqlClient 数据提供程序将 SQL Server 用作数据源。System.Data.SqlClient 提供程序支持作为占位符的命名参数,如以下示例所示:
SELECT * FROM Employees WHERE LastName = @LastName AND FirstName = @FirstName
使用命名参数,在命令的参数集合中指定参数的顺序并不重要。但是,必须确保在 SQL 命令中使用的参数名称与相关集合中的参数名称相对应。
下面的示例演示如何将 SQL 命令中的命名参数用于使用 System.Data.SqlClient 提供程序的 SqlDataSource 控件。
<asp:sqlDataSource ID="EmployeeDetailsSqlDataSource" SelectCommand="SELECT EmployeeID, LastName, FirstName FROM Employees WHERE EmployeeID = @EmpID" InsertCommand="INSERT INTO Employees(LastName, FirstName) VALUES (@LastName, @FirstName); SELECT @EmpID = SCOPE_IDENTITY()" UpdateCommand="UPDATE Employees SET LastName=@LastName, FirstName=@FirstName WHERE EmployeeID=@EmployeeID" DeleteCommand="DELETE Employees WHERE EmployeeID=@EmployeeID" ConnectionString="<%$ ConnectionStrings:NorthwindConnection %>" OnInserted="EmployeeDetailsSqlDataSource_OnInserted" RunAt="server"> <SelectParameters> <asp:Parameter Name="EmpID" Type="Int32" DefaultValue="0" /> </SelectParameters> <InsertParameters> <asp:Parameter Name="EmpID" Direction="Output" Type="Int32" DefaultValue="0" /> </InsertParameters> </asp:sqlDataSource>
<asp:sqlDataSource ID="EmployeeDetailsSqlDataSource"
SelectCommand="SELECT EmployeeID, LastName, FirstName FROM Employees WHERE EmployeeID = @EmpID"
InsertCommand="INSERT INTO Employees(LastName, FirstName) VALUES (@LastName, @FirstName);
SELECT @EmpID = SCOPE_IDENTITY()"
UpdateCommand="UPDATE Employees SET LastName=@LastName, FirstName=@FirstName
WHERE EmployeeID=@EmployeeID"
DeleteCommand="DELETE Employees WHERE EmployeeID=@EmployeeID"
ConnectionString="<%$ ConnectionStrings:NorthwindConnection %>"
OnInserted="EmployeeDetailsSqlDataSource_OnInserted"
RunAt="server">
<SelectParameters>
<asp:Parameter Name="EmpID" Type="Int32" DefaultValue="0" />
</SelectParameters>
<InsertParameters>
<asp:Parameter Name="EmpID" Direction="Output" Type="Int32" DefaultValue="0" />
</InsertParameters>
</asp:sqlDataSource>
如果要连接到 OLE 数据库或 ODBC 数据源,可以对 SqlDataSource 控件进行配置,使其通过 System.Data.OleDb 或 System.Data.Odbc 提供程序分别使用数据源。System.Data.OleDb 和 System.Data.Odbc 提供程序只支持由“?”字符标识的定位参数,如以下示例所示:
SELECT * FROM Employees WHERE LastName = ? AND FirstName = ?
将 System.Data.OleDb 和 System.Data.Odbc 提供程序与参数化 SQL 语句结合使用时,参数占位符的指定顺序必须与相关参数集合中的参数顺序匹配。可以控制参数的顺序,方法是在执行相关数据操作的集合(如相关 UpdateCommand 的 UpdateParameters 集合)中显式指定这些参数。为通过数据绑定控件传递的值自动创建的参数显式创建参数集合时,显式创建的参数将会改写自动生成的所有参数。这样,可以确保参数按照所需的顺序进行传递。
注意 |
|---|
|
默认情况下,数据绑定控件中基于绑定字段的参数将按照下列顺序从参数字典添加到命令中:Values、Keys 和 OldValues。对于删除操作,只使用 Keys 字典。对于插入操作,只使用 Values 字典。有关数据绑定控件传递的字典的更多信息,请参见数据源控件如何为数据绑定字段创建参数。 |
下面的示例演示如何为使用 System.Data.OleDb 提供程序的 SqlDataSource 控件指定参数。为了确保集合中的参数顺序与 SQL 语句中占位符的顺序匹配,可以显式指定这些参数。
<Fields> <asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" InsertVisible="False" ReadOnly="true"/> <asp:BoundField DataField="FirstName" HeaderText="First Name"/> <asp:BoundField DataField="LastName" HeaderText="Last Name"/> <asp:TemplateField HeaderText="Birth Date"> <ItemTemplate> <asp:Label ID="BirthDateLabel" Runat="Server" Text='<%# Eval("BirthDate", "{0:d}") %>' /> </ItemTemplate> <InsertItemTemplate> <asp:Calendar ID="InsertBirthDateCalendar" Runat="Server" SelectedDate='<%# Bind("BirthDate") %>' /> </InsertItemTemplate> <EditItemTemplate> <asp:Calendar ID="EditBirthDateCalendar" Runat="Server" VisibleDate='<%# Eval("BirthDate") %>' SelectedDate='<%# Bind("BirthDate") %>' /> </EditItemTemplate> </asp:TemplateField> </Fields>
<Fields>
<asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" InsertVisible="False" ReadOnly="true"/>
<asp:BoundField DataField="FirstName" HeaderText="First Name"/>
<asp:BoundField DataField="LastName" HeaderText="Last Name"/>
<asp:TemplateField HeaderText="Birth Date">
<ItemTemplate>
<asp:Label ID="BirthDateLabel" Runat="Server"
Text='<%# Eval("BirthDate", "{0:d}") %>' />
</ItemTemplate>
<InsertItemTemplate>
<asp:Calendar ID="InsertBirthDateCalendar" Runat="Server"
SelectedDate='<%# Bind("BirthDate") %>' />
</InsertItemTemplate>
<EditItemTemplate>
<asp:Calendar ID="EditBirthDateCalendar" Runat="Server"
VisibleDate='<%# Eval("BirthDate") %>'
SelectedDate='<%# Bind("BirthDate") %>' />
</EditItemTemplate>
</asp:TemplateField>
</Fields>