下面将展示如何从 SQL Server 检索图像并将其显示在 ASP.NET 网页上的 GridView 中。
在数据库中创建表:
CREATE TABLE Surplus([Surplus Id] int not null,
Department nchar(50),
Category nchar(25),
Item nchar(75),
Visible bit,
TransferableImage varbinary(max),
CONSTRAINT PK_Surplus_SurplusId PRIMARY KEY([Surplus Id]));
注意:如果表格列名中包含空格,则需要用[] 括起来。我更喜欢创建没有空格的数据库列名。
在开始之前,请确保安装了适当的 Visual Studio 工作负载/单个组件。
VS 2017:
- 打开 Visual Studio 安装程序
- 点击修改
- 点击工作负载标签
- 确保检查以下内容:.NET 桌面开发、ASP.NET 和 Web 开发、数据存储和处理
- 点击单个组件
- 在 .NET 下,检查:.NET Framework 4.7.2 SDK 和 .NET Framework 4.7.2 目标包
- 在“代码工具”下,选中 ClickOnce Publishing 和 NuGet 包管理器
- 选择全部下载,然后安装
- 点击修改
VS 2017:
创建一个新项目
- 打开 Visual Studio
- 点击文件
- 选择新建
- 选择项目
- 点击左侧的Visual Basic
- 点击左侧的Web
- 选择ASP.NET Web 应用程序(.NET Framework);对于“框架”,选择 .NET Framework 4.7.2
- 点击确定
- 选择空
- 点击确定
注意:确保Option Strict已开启。
查找您的 Windows 服务器名称:
查找您的 SQL Server 实例名称:
- 打开一个cmd窗口
- 类型:
sc query | find /i "SQL Server"
注意:您会看到类似以下内容:DISPLAY_NAME: SQL Server (SQLEXPRESS)。 SQL Server 实例名称在() 内。在本例中,SQL Server 实例名称为:SQLEXPRESS
我们将使用以下内容:
-
Windows 服务器名称:ICTSQL
-
SQL Server 实例名称:ICTSQL
-
数据库名称:ICTSQL
-
身份验证类型:Windows身份验证
注意:我不建议将 Windows 服务器、数据库实例和数据库名称命名为相同的名称,因为这会导致混淆。但是,我的理解是,截至发帖时,他们目前的名字都是ICTSQL。
打开解决方案资源管理器
将连接字符串添加到 Web.config
- 在解决方案资源管理器中,双击 Web.config
在下面的代码中,根据您的环境修改<connectionStrings>...</connectionStrings> 中的代码。请参阅SQL Server connection strings 了解更多信息。
Web.config
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
https://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<connectionStrings>
<add name="ictsqlConnection" connectionString="Data Source=.\SQLEXPRESS;Database=ICTSQL;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False" providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.7.2"/>
<httpRuntime targetFramework="4.7.2"/>
</system.web>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701"/>
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+"/>
</compilers>
</system.codedom>
</configuration>
在下面的代码中,我改编了来自this post的菜单代码
打开属性窗口
将 XML 文件添加到项目中(名称:insuranceMenu.xml)
- 在VS菜单中,点击Project
- 选择添加新项目...
- 在左侧,点击数据
- 单击XML 文件(名称:surveyMenu.xml)
- 在“属性”窗口中,将复制到输出目录设置为始终复制
surplusMenu.xml:
<?xml version="1.0" encoding="utf-8" ?>
<surplusMenu text="Home" url="./default.aspx">
<main text="Surplus" url="./addDatabaseRecord.aspx">
<page text="Add Record" url ="./addDatabaseRecord.aspx" />
</main>
</surplusMenu>
添加模块(名称:Module1.vb)
- 在解决方案资源管理器中,右键单击 (例如:
DatabaseGridViewTest)
- 选择添加
- 选择新项目...
- 在左侧,点击代码
- 选择模块(名称:Module1.vb)
- 点击添加
Module1.vb
Imports System.Drawing
Imports System.IO
Module Module1
Public Function ResizeImage(imageBytes As Byte(), maxWidth As Integer, maxHeight As Integer) As Byte()
Dim modifiedImageBytes As Byte()
Dim ratioX As Double = 0
Dim ratioY As Double = 0
Dim ratio As Double = 0
Dim newWidth As Integer = 0
Dim newHeight As Integer = 0
Using ms As MemoryStream = New MemoryStream(imageBytes)
Using originalImg As Bitmap = New Bitmap(ms)
ratioX = CType(maxWidth, Double) / originalImg.Width
ratioY = CType(maxHeight, Double) / originalImg.Height
'set value
ratio = Math.Min(ratioX, ratioY)
'calculate new width and height
newWidth = CType((CType(originalImg.Width, Double) * ratio), Integer)
newHeight = CType((CType(originalImg.Height, Double) * ratio), Integer)
'create new Bitmap with desired size
Using newImg As Bitmap = New Bitmap(newWidth, newHeight)
Using g As Graphics = Graphics.FromImage(newImg)
g.DrawImage(originalImg, 0, 0, newWidth, newHeight)
g.Save()
End Using
Using newImgMs As MemoryStream = New MemoryStream()
'save in jpeg format
newImg.Save(newImgMs, Imaging.ImageFormat.Jpeg)
'save as Byte()
modifiedImageBytes = newImgMs.ToArray()
End Using
End Using
End Using
End Using
Return modifiedImageBytes
End Function
End Module
添加WebForm(名称:addDatabaseRecord.aspx)
- 在解决方案资源管理器中,右键单击 (例如:
DatabaseGridViewTest)
- 选择添加
- 选择新项目...
- 选择Web表单(名称:addDatabaseRecord.aspx)
- 点击添加
addDatabaseRecord.aspx
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="addDatabaseRecord.aspx.vb" Inherits="DatabaseGridViewTest.addDatabaseRecord" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<!-- menu -->
<div id="menu" style="background-color:cornflowerblue" >
<asp:XmlDataSource runat="server" ID="xmldatasource" DataFile="surplusMenu.xml"></asp:XmlDataSource>
<asp:Menu ID="menuNavigator" runat="server" Width="760px" DisappearAfter="0" StaticSubMenuIndent="10px" StaticEnableDefaultPopOutImage="False" Orientation="Horizontal" StaticDisplayLevels="2" DataSourceID="xmldatasource" ItemWrap="True" >
<StaticHoverStyle Height="34px" Width="50px" BackColor="#93C6FF" />
<StaticMenuItemStyle HorizontalPadding="8px" Width="50px" Height="34px" CssClass="menustyle" ForeColor="Black" VerticalPadding="2px" />
<DynamicMenuStyle Width="50px" />
<DynamicSelectedStyle BackColor="#507CD1"></DynamicSelectedStyle>
<DynamicHoverStyle BackColor="#6597F0" ForeColor="White" Font-Bold="True" />
<DynamicMenuItemStyle BackColor="#0A398D" Width="125px" HorizontalPadding="15px" VerticalPadding="6px" ForeColor="White" Font-Size="14px" />
<DataBindings>
<asp:MenuItemBinding DataMember="surplusMenu" TextField="text" NavigateUrlField="url"></asp:MenuItemBinding>
<asp:MenuItemBinding DataMember="main" NavigateUrlField="url" TextField="text"></asp:MenuItemBinding>
<asp:MenuItemBinding DataMember="page" NavigateUrlField="url" TextField="text"></asp:MenuItemBinding>
</DataBindings>
</asp:Menu>
</div>
<div style="position:absolute;left:300px">
<h2>Surplus Record Entry</h2>
</div>
<div>
<!-- Surplus Id -->
<asp:Label ID="LabelSurplusId" runat="server" Text="Surplus Id:" style="position:absolute;left:50px;top:100px;font-weight:bold"></asp:Label>
<asp:TextBox ID="TextBoxSurplusId" runat="server" style="position:absolute;left:200px;top:100px;width:75px" ></asp:TextBox>
<!-- Department, Category -->
<asp:Label ID="LabelDepartment" runat="server" Text="Department:" style="position:absolute;left:50px;top:140px;font-weight:bold"></asp:Label>
<asp:TextBox ID="TextBoxDepartment" runat="server" style="position:absolute;left:200px;top:140px;width:150px"></asp:TextBox>
<asp:Label ID="LabelCategory" runat="server" Text="Category:" style="position:absolute;left:450px;top:140px;font-weight:bold"></asp:Label>
<asp:TextBox ID="TextBoxCategory" runat="server" style="position:absolute;left:550px;top:140px;width:150px"></asp:TextBox>
<!-- Item, IsVisible -->
<asp:Label ID="LabelItem" runat="server" Text="Item:" style="position:absolute;left:50px;top:180px;font-weight:bold"></asp:Label>
<asp:TextBox ID="TextBoxItem" runat="server" style="position:absolute;left:200px;top:180px;width:150px"></asp:TextBox>
<asp:CheckBox ID="CheckBoxIsVisible" runat="server" style="position:absolute;left:448px;top:180px;width:125px;font-weight:bold" Text=" Is Visible?" Checked="true"/>
<!-- Transferable Image -->
<asp:Label ID="LabelTransferableImage" runat="server" Text="Transferable Image:" style="position:absolute;left:50px;top:220px;font-weight:bold"></asp:Label>
<asp:FileUpload ID="FileUploadTransferableImage" runat="server" style="position:absolute;left:200px;top:220px;font-weight:bold"/>
</div>
<div>
<asp:Button ID="ButtonSave" runat="server" Text="Save" style="position:absolute;left:350px;top:280px;height:40px;width:125px" OnClick="ButtonSave_Click" />
</div>
<div>
<asp:Label ID="LabelMsg" runat="server" Text="" style="position:absolute;left:350px;top:340px"></asp:Label>
</div>
</form>
</body>
</html>
在解决方案资源管理器中,右键单击 addDatabaseRecord.aspx。选择查看代码
addDatabaseRecord.aspx.vb
注意:如果(数据库)表列名包含空格,则需要用[]包围。
Imports System.Configuration
Imports System.Data.SqlClient
Public Class addDatabaseRecord
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
SetSurplusId()
End Sub
Protected Sub ClearPage()
TextBoxSurplusId.Text = String.Empty
TextBoxDepartment.Text = String.Empty
TextBoxCategory.Text = String.Empty
TextBoxItem.Text = String.Empty
CheckBoxIsVisible.Checked = True
'dispose
FileUploadTransferableImage.Dispose()
'create new instance
FileUploadTransferableImage = New FileUpload()
End Sub
Private Function GetNextSurplusId() As Integer
Dim nextSurplusId As Integer = 0
Dim connectionStr As String = ConfigurationManager.ConnectionStrings("ictsqlConnection").ConnectionString
Dim sqlText As String = "SELECT Max([Surplus Id]) from Surplus;"
Using con As SqlConnection = New SqlConnection(connectionStr)
'open
con.Open()
Using cmd As SqlCommand = New SqlCommand(sqlText, con)
'get last surplus id from database and increment it by 1
nextSurplusId = (DirectCast(cmd.ExecuteScalar(), Integer)) + 1
End Using
End Using
Return nextSurplusId
End Function
Protected Function SaveSurplusRecord(surplusId As Integer, department As String, category As String, item As String, visible As Boolean, transferableImageBytes As Byte()) As Integer
Dim rowsAffected As Integer = 0
Dim connectionStr As String = ConfigurationManager.ConnectionStrings("ictsqlConnection").ConnectionString
Dim sqlText As String = "INSERT INTO Surplus([Surplus Id], Department, Category, Item, Visible, TransferableImage) VALUES(@surplusId, @department, @category, @item, @visible, @transferableImage);"
Using con As SqlConnection = New SqlConnection(connectionStr)
'open
con.Open()
Using cmd As SqlCommand = New SqlCommand(sqlText, con)
cmd.Parameters.Add("@surplusId", SqlDbType.Int).Value = surplusId
If String.IsNullOrEmpty(department) Then
cmd.Parameters.Add("@department", SqlDbType.NChar).Value = DBNull.Value
Else
cmd.Parameters.Add("@department", SqlDbType.NChar).Value = department
End If
If String.IsNullOrEmpty(category) Then
cmd.Parameters.Add("@category", SqlDbType.NChar).Value = DBNull.Value
Else
cmd.Parameters.Add("@category", SqlDbType.NChar).Value = category
End If
If String.IsNullOrEmpty(item) Then
cmd.Parameters.Add("@item", SqlDbType.NChar).Value = DBNull.Value
Else
cmd.Parameters.Add("@item", SqlDbType.NChar).Value = item
End If
'size = -1 is needed to exceed 8000 bytes; it maps to varbinary(max)
cmd.Parameters.Add("@transferableImage", SqlDbType.VarBinary, -1).Value = transferableImageBytes
'execute
rowsAffected = cmd.ExecuteNonQuery()
End Using
End Using
Return rowsAffected
End Function
Private Sub SetSurplusId()
Dim nextSurplusId As Integer = GetNextSurplusId()
If nextSurplusId > 0 Then
TextBoxSurplusId.Text = nextSurplusId.ToString()
End If
End Sub
Protected Sub ButtonSave_Click(sender As Object, e As EventArgs)
If FileUploadTransferableImage.HasFile() Then
LabelMsg.Text = "Filename: " & FileUploadTransferableImage.FileName & " File bytes: " & FileUploadTransferableImage.FileBytes.Length
Dim surplusIdInt As Integer = 0
If Int32.TryParse(TextBoxSurplusId.Text, surplusIdInt) Then
'save record to database
Dim rowsAffected As Integer = SaveSurplusRecord(surplusIdInt, TextBoxDepartment.Text, TextBoxCategory.Text, TextBoxItem.Text, CheckBoxIsVisible.Checced, FileUploadTransferableImage.FileBytes())
If rowsAffected > 0 Then
LabelMsg.Text = String.Format("Record saved (Surplus Id: {0}; Item: {1})", surplusIdInt.ToString(), TextBoxItem.Text)
ClearPage()
SetSurplusId()
'System.Threading.Thread.Sleep(1000)
'Response.Redirect("addDatabaseRecord.aspx")
Else
LabelMsg.Text = String.Format("Error: Record not saved (Surplus Id: {0}; Item: {1})", surplusIdInt.ToString(), TextBoxItem.Text)
End If
Else
LabelMsg.Text = String.Format("Error: Surplus Id must be an integer. (Surplus Id: '{0}')", TextBoxSurplusId.Text)
End If
Else
LabelMsg.Text = "Error: Transferable image has not been selected."
End If
End Sub
End Class
添加WebForm(名称:default.aspx)
- 在解决方案资源管理器中,右键单击 (例如:
DatabaseGridViewTest)
- 选择添加
- 选择新项目...
- 选择Web 表单(名称:default.aspx)
- 点击添加
default.aspx
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="default.aspx.vb" Inherits="DatabaseGridViewTest._default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<!-- menu -->
<div id="menu" style="background-color:cornflowerblue" >
<asp:XmlDataSource runat="server" ID="xmldatasource" DataFile="surplusMenu.xml"></asp:XmlDataSource>
<asp:Menu ID="menuNavigator" runat="server" Width="760px" DisappearAfter="0" StaticSubMenuIndent="10px" StaticEnableDefaultPopOutImage="False" Orientation="Horizontal" StaticDisplayLevels="2" DataSourceID="xmldatasource" ItemWrap="True" >
<StaticHoverStyle Height="34px" Width="50px" BackColor="#93C6FF" />
<StaticMenuItemStyle HorizontalPadding="8px" Width="50px" Height="34px" CssClass="menustyle" ForeColor="Black" VerticalPadding="2px" />
<DynamicMenuStyle Width="50px" />
<DynamicSelectedStyle BackColor="#507CD1"></DynamicSelectedStyle>
<DynamicHoverStyle BackColor="#6597F0" ForeColor="White" Font-Bold="True" />
<DynamicMenuItemStyle BackColor="#0A398D" Width="125px" HorizontalPadding="15px" VerticalPadding="6px" ForeColor="White" Font-Size="14px" />
<DataBindings>
<asp:MenuItemBinding DataMember="surplusMenu" TextField="text" NavigateUrlField="url"></asp:MenuItemBinding>
<asp:MenuItemBinding DataMember="main" NavigateUrlField="url" TextField="text"></asp:MenuItemBinding>
<asp:MenuItemBinding DataMember="page" NavigateUrlField="url" TextField="text"></asp:MenuItemBinding>
</DataBindings>
</asp:Menu>
</div>
<div>
<asp:Label ID="LabelMsg" runat="server" Text="" style="position:absolute;left:50px; top:60px"></asp:Label>
</div>
<div style="position:absolute;left:50px; top:100px">
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="Surplus Id" GridLines="Both">
<Columns>
<asp:BoundField DataField="Surplus Id" HeaderText="Surplus Id" ItemStyle-HorizontalAlign="Center" Visible="True" />
<asp:BoundField DataField="Department" HeaderText="Department" ItemStyle-HorizontalAlign="Center" />
<asp:BoundField DataField="Category" HeaderText="Category" ItemStyle-HorizontalAlign="Center" />
<asp:BoundField DataField="Item" HeaderText="Item" ItemStyle-HorizontalAlign="Left" />
<asp:BoundField DataField="Visible" HeaderText="Visible" ItemStyle-HorizontalAlign="Center" />
<asp:TemplateField HeaderText="Transferable Image" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Image ID="TransferableImg" runat="server" ImageUrl='<%# Eval("TransferableImageBase64", "{0}") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
在解决方案资源管理器中,右键单击 default.aspx。选择查看代码
default.aspx.vb
注意:如果(数据库)表列名包含空格,则必须用[] 将其括起来。此外,在下面的代码中,图像在加载时会调整大小。最好在将每个图像保存到数据库时调整其大小,这样就不必在每次加载时都调整大小。
Imports System.Configuration
Imports System.Data.SqlClient
Imports System.Drawing
Imports System.IO
Public Class _default
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim connectionStr As String = ConfigurationManager.ConnectionStrings("ictsqlConnection").ConnectionString
Using con As SqlConnection = New SqlConnection(connectionStr)
'open
con.Open()
Using cmd As SqlCommand = New SqlCommand("SELECT [Surplus Id], Department, Category, Item, Visible, TransferableImage FROM Surplus", con)
Using da As SqlDataAdapter = New SqlDataAdapter(cmd)
Dim dt As DataTable = New DataTable()
'fill DataTable with data from database
da.Fill(dt)
'add column that will store the image as a base64 string
dt.Columns.Add("TransferableImageBase64", GetType(System.String))
For i As Integer = 0 To dt.Rows.Count - 1
'convert image Byte() from database to base64 string and store in a new column in the DataTable
'dt(i)("TransferableImageBase64") = "data:image/jpg;base64," & Convert.ToBase64String(CType(dt(i)("TransferableImage"), Byte()))
'resize image to desired size and convert image Byte() to base64 string, and store in a new column in the DataTable
dt(i)("TransferableImageBase64") = "data:image/jpg;base64," & Convert.ToBase64String(ResizeImage(CType(dt(i)("TransferableImage"), Byte()), 50, 50))
Next
'remove column that contains Byte() from DataTable
dt.Columns.Remove("TransferableImage")
GridView1.DataSource = dt
GridView1.DataBind()
End Using
End Using
End Using
End Sub
End Class
这是一个演示:
查找 IIS 应用程序池的名称
赢得 10:
- 打开控制面板(查看方式:小图标)
- 双击管理工具
- 双击 Internet 信息服务 (IIS) 管理器
- 展开
- 展开网站
- 右键单击所需网站
- 选择管理网站
- 选择高级设置...
- 记下
Application Pool 的属性值(例如:ICTSQL)
下面展示了如何将 IIS 用户 (NT AUTHORITY\IUSR) 添加到 SQL Server,如何将其添加到数据库,以及如何授予它对表的权限。 (这假设 SQL Server 和 IIS(Web 服务器)都在同一台服务器上运行。您还需要为 IIS APPPOOL 用户(例如:IIS APPPOOL\ICTSQL)重复此过程。
下载/安装 SQL Server Management Studio (SSMS)
创建数据库用户
- 打开 Microsoft SQL Server Management Studio
- 展开安全
- 右键单击登录
- 选择新登录
- 选择 Windows 身份验证
- 登录名:
NT AUTHORITY\IUSR
- 选择所需的默认数据库(例如:ICTSQL)
- 点击确定
将用户添加到数据库
- 打开 Microsoft SQL Server Management Studio
- 扩展数据库
- 扩展(例如:ICTSQL)
- 展开安全
- 右键单击用户
- 选择新用户...
- 用户名:
NT AUTHORITY\IUSR
- 对于“登录名”,点击
...
- 点击浏览
- 选择
NT AUTHORITY\IUSR
- 点击确定
- 点击确定
- 将“默认架构”留空。
- 点击确定
授予用户对表的权限
- 打开 Microsoft SQL Server Management Studio
- 扩展数据库
- 扩展(例如:ICTSQL)
- 展开表格
- 右键单击(例如:dbo.Surplus)
- 选择属性
- 在“选择页面”下,点击权限
- 点击搜索
- 点击浏览
- 检查所需用户(例如:
NT AUTHORITY\IUSR)
- 点击确定
- 点击确定
- 在Grant下,检查以下内容:Delete、Insert、Select、Update、References(您可能还想授予:View change tracking、View definition)李>
- 点击确定
注意:“With Grant”允许用户将权限授予另一个用户。
对“IIS APPPOOL”用户重复上述过程。(例如:IIS APPPOOL\ICTSQL)
资源: