下面将展示如何从 SQL Server 检索图像并将其显示在GridView
在 ASP.NET 网页上。
在数据库中创建一个表:
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]));
Note:如果表列名包含空格,则需要将其括起来[]
。我更喜欢创建不带空格的数据库列名称。
开始之前,请确保安装了适当的 Visual Studio 工作负载/单独组件。
VS 2017:
- Open 视觉工作室安装程序
- Click Modify
- Click 工作负载 tab
- 确保检查以下内容:.NET 桌面开发、ASP.NET 和 Web 开发、数据存储和处理
- Click 单独的组件
- 在 .NET 下,检查:.NET框架4.7.2 SDK and .NET Framework 4.7.2 目标包
- 在“代码工具”下,检查ClickOnce发布 and NuGet 包管理器
- Select 全部下载,然后安装
- Click Modify
VS 2017:
创建一个新项目
- 打开视觉工作室
- Click File
- Select New
- Select Project
- 在左侧,单击视觉基础
- 在左侧,单击Web
- Select ASP.NET Web 应用程序(.NET 框架);对于“框架”,选择.NET框架4.7.2
- Click OK
- Select Empty
- Click OK
Note: 确保选项严格 https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/option-strict-statement已打开。
查找您的 Windows 服务器名称:
查找您的 SQL Server 实例名称:
- 打开cmd窗口
- type:
sc query | find /i "SQL Server"
Note: 你会看到类似下面的内容:DISPLAY_NAME: SQL Server (SQLEXPRESS)
。 SQL Server 实例名称位于()
。在本例中,SQL Server 实例名称为:SQLEXPRESS
我们将使用以下内容:
-
Windows 服务器名称: ICTSQL
-
SQL Server 实例名称: ICTSQL
-
数据库名称: ICTSQL
-
认证类型:Windows 身份验证
Note:我不建议将 Windows 服务器、数据库实例和数据库名称命名为相同的名称,因为这可能会导致混乱。然而,我的理解是,截至发帖时,他们目前都有这个名字ICTSQL
.
打开解决方案资源管理器
- 在 VS 菜单中,单击View
- Select 解决方案浏览器
将连接字符串添加到 Web.config
在下面的代码中,修改里面的代码<connectionStrings>...</connectionStrings>
为了您的环境。看SQL Server 连接字符串 https://www.connectionstrings.com/microsoft-data-sqlclient/了解更多信息。
网页配置
<?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>
在下面的代码中,我改编了菜单的代码这个帖子 https://social.msdn.microsoft.com/Forums/en-US/1819233e-113b-4c35-b474-c831eb332cf1/creating-menu-bar-in-aspnet?forum=aspwebforms
打开属性窗口
- 在 VS 菜单中,单击View
- Select 属性窗口
将 XML 文件添加到项目中(名称:剩余菜单.xml)
- 在 VS 菜单中,单击Project
- Select 添加新项目...
- 在左侧,单击Data
- Click XML File(名称:剩余菜单.xml)
- 在属性窗口中,设置复制到输出目录 to 始终复制
剩余菜单.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
)
- Select Add
- Select 新物品...
- 在左侧,单击Code
- Select Module(名称:Module1.vb)
- Click Add
模块1.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
添加网页表单(名称:addDatabaseRecord.aspx)
- 在解决方案资源管理器中,右键单击 (例如:
DatabaseGridViewTest
)
- Select Add
- Select 新物品...
- Select Web Form(名称:addDatabaseRecord.aspx)
- Click Add
添加数据库记录.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>
在解决方案资源管理器中,右键单击添加数据库记录.aspx。选择查看代码
添加数据库记录.aspx.vb
Note:如果(数据库)表列名包含空格,则需要将其括起来[]
.
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
添加网页表单(名称:默认.aspx)
- 在解决方案资源管理器中,右键单击 (例如:
DatabaseGridViewTest
)
- Select Add
- Select 新物品...
- Select Web Form(名称:默认.aspx)
- Click Add
默认.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>
在解决方案资源管理器中,右键单击默认.aspx。选择查看代码
默认.aspx.vb
Note:如果(数据库)表列名包含空格,则需要将其括起来[]
。此外,在下面的代码中,图像在加载时会调整大小。最好在将每个图像保存到数据库时调整其大小,这样就不必在每次加载时都调整大小。
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 应用程序池的名称
Win 10:
- Open 控制面板(查看方式:小图标)
- 双击管理工具
- 双击Internet 信息服务 (IIS) 管理器
- 展开
- Expand Sites
- 右键单击所需的网站
- Select 管理网站
- Select 高级设置...
- 写下财产价值
Application Pool
(例如:ICTSQL)
下面展示了如何添加 IIS 用户(NT AUTHORITY\IUSR
)到 SQL Server,如何将其添加到数据库,以及如何授予其对表的权限。 (这假设 SQL Server 和 IIS(Web 服务器)在同一台服务器上运行。您需要为 IIS APPPOOL 用户重复此过程(例如:IIS APPPOOL\ICTSQL
)也是如此。
下载/安装 SQL Server 管理工作室 (SSMS) https://learn.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver15
创建数据库用户
- Open 微软 SQL Server 管理工作室
- Expand Security
- 右键点击Logins
- Select 新登录
- Select Windows 身份验证
- 登录名:
NT AUTHORITY\IUSR
- 选择所需的默认数据库(例如:ICTSQL)
- Click OK
将用户添加到数据库
- Open 微软 SQL Server 管理工作室
- Expand 数据库
- 展开(例如:ICTSQL)
- Expand Security
- 右键点击Users
- Select 新用户...
- 用户名:
NT AUTHORITY\IUSR
- 对于“登录名”,请单击
...
- Click Browse
- Select
NT AUTHORITY\IUSR
- Click OK
- Click OK
- 将“默认架构”留空。
- Click OK
授予用户对表的权限
- Open 微软 SQL Server 管理工作室
- Expand 数据库
- 展开(例如:ICTSQL)
- Expand Tables
- 右键单击(例如:dbo.Surplus)
- Select 特性
- 在“选择页面”下,单击权限
- Click Search
- Click Browse
- 检查所需的用户(例如:
NT AUTHORITY\IUSR
)
- Click OK
- Click OK
- Under Grant,检查以下内容:删除、插入、选择、更新、引用(您可能还想授予:视图更改跟踪、视图定义)
- Click OK
Note:“With Grant”允许用户将权限授予其他用户。
对“IIS APPPOOL”用户重复上述过程。 (ex: IIS APPPOOL\ICTSQL
)
资源:
- 将连接字符串存储在 Web.config 中 https://www.connectionstrings.com/store-connection-string-in-webconfig/
- SQL Server 连接字符串 https://www.connectionstrings.com/microsoft-data-sqlclient/
- 如何在 HTML 中显示 Base64 图像 https://stackoverflow.com/questions/8499633/how-to-display-base64-images-in-html
- 在 ASP.NET 中使用 RowDataBound 在 gridview 中显示图像 https://stackoverflow.com/questions/29919776/displaying-image-in-gridview-with-rowdatabound-in-asp-net
- 根据 C# 和 VB.Net 中的列值在 ASP.Net GridView 中分配图像 URL https://www.aspsnippets.com/questions/111703/Assign-Image-URL-in-ASPNet-GridView-based-on-column-value-in-C-and-VBNet/
- 在 ASP.NET 中绑定 GridView 一步一步 https://www.c-sharpcorner.com/UploadFile/8a67c0/bind-gridview-in-Asp-Net-step-by-step/
- 使用 MaxHeight 和 MaxWidth 约束按比例调整图像大小 https://stackoverflow.com/questions/6501797/resize-image-proportionally-with-maxheight-and-maxwidth-constraints
- 如何控制ASP.NET控件在页面中的位置 https://stackoverflow.com/questions/1190359/how-to-control-asp-net-controls-location-in-the-page
- 在asp.net中创建菜单栏 https://social.msdn.microsoft.com/Forums/en-US/1819233e-113b-4c35-b474-c831eb332cf1/creating-menu-bar-in-aspnet?forum=aspwebforms
- 选项严格 https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/option-strict-statement
- 添加 IIS 7 AppPool 身份作为 SQL Server 登录 https://stackoverflow.com/questions/1933134/add-iis-7-apppool-identities-as-sql-server-logons