使用 EF 和 ASP.NET 在 SQL Server 中存储图像






4.55/5 (35投票s)
一个关于在 SQL Server 中存储图像并在 ASP.NET 网站上显示图像的快速教程
引言
这篇文章实际上是源于论坛上对这个主题知识的需求。关于如何将二进制数据(图像)存储在 SQL Server 数据库中以及如何检索它们,甚至如何使用 ASP.NET (MVC) 将图像返回以在网站上显示的问题。对于 ASP.NET WebForms 开发者,我也包含了一个 ASP.NET WebForms 示例项目。
背景
该解决方案包含两个演示项目。一个 ASP.NET WebForms 项目和一个 ASP.NET MVC 4 项目。MVC 演示项目包含两个控制器。一个 HomeController
和一个 DocumentController
。DocumentController
包含两个上传和下载图像的操作方法。HomeController
使用这些方法来上传和显示数据库中的图像。为了更好地展示上传功能,我包含了 dropzone.js (http://www.dropzonejs.com/)。
ASP.NET WebForms 项目包含一个单独的 Web 窗体和两个通用处理程序。一个处理程序处理上传,另一个处理从数据库上传输图像。然后,Web 窗体使用这些处理程序来发送和获取图像。
设置数据库
我假设您熟悉 SQL Server 数据库。我创建了一个名为 Document
的表,其结构如下:
[请注意,下载演示项目时,需要更改 ASP.NET 项目的 web.config
文件中的名为 DocumentEntities
的连接字符串]
如果打开 Entity Framework 数据模型 (DocumentEntities.edmx) 图,上面的表将显示如下
Using the Code
为了保持简单,我向解决方案添加了另一个项目,一个简单的类库项目,其中将包含我从包含 Document
表的数据库创建的 Entity Framework 模型。
一点 MVC
我创建了一个新控制器,我称之为 HomeController
,并选择了“Empty MVC Controller”(空 MVC 控制器)作为模板。这个控制器通过返回 Index 操作方法的视图就足够了。
操作方法如下(是的,我知道,魔术并不在这里发生,但为了完整性,我还是想添加它们)。
[HttpGet]
public ActionResult Show(int? id)
{
string mime;
byte[] bytes = LoadImage(id.Value, out mime);
return File(bytes, mime);
}
上面的方法调用了一个函数,该函数检索文件类型和文件的 byte[]
,并返回一个 File
对象。int? id
将用于根据数据库中的记录 ID 查找图像。
[HttpPost]
public ActionResult Upload()
{
SuccessModel viewModel = new SuccessModel();
if (Request.Files.Count == 1)
{
var name = Request.Files[0].FileName;
var size = Request.Files[0].ContentLength;
var type = Request.Files[0].ContentType;
viewModel.Success = HandleUpload(Request.Files[0].InputStream, name, size, type);
}
return Json(viewModel);
}
此操作方法将由 dropzone.js 使用。Dropzone 发布有关正在上传的文件的一些信息,当然还有文件的二进制数据。所有值都传递给 HandleUpload
方法,该方法将文件存储在数据库中。
一点 WebForms
对于 ASP.NET WebForms 项目,我添加了一个 WebForm
(并称之为 Default.aspx)。这个 Web 窗体没有代码隐藏,只有一些 HTML 和 JavaScript,顺便说一下,它们与 MVC 版本渲染的 HTML 非常相似。有一个小区别,上传表单的 post 地址,以及触发图像更新的 JavaScript 使用的是不同的地址。
展示魔力
好了,现在这是您想看到的!实际将文件放入数据库并从数据库读取图像的方法。您准备好了吗?我们开始吧。
private bool HandleUpload(Stream fileStream, string name, int size, string type)
{
bool handled = false;
try
{
byte[] documentBytes = new byte[fileStream.Length];
fileStream.Read(documentBytes, 0, documentBytes.Length);
Document databaseDocument = new Document
{
CreatedOn = DateTime.Now,
FileContent = documentBytes,
IsDeleted = false,
Name = name,
Size = size,
Type = type
};
using (DocumentEntities databaseContext = new DocumentEntities())
{
databaseContext.Documents.Add(databaseDocument);
handled = (databaseContext.SaveChanges() > 0);
}
}
catch (Exception ex)
{
// Oops, something went wrong, handle the exception
}
return handled;
}
首先,我们创建一个字节数组,因为 EntityFramework
就是这样映射二进制文件类型的。然后我们将传入的流(文件)读取到字节数组中。然后我们创建一个新的 Document
对象,它是我们数据库表的表示。然后我们实例化数据库上下文,并将文档添加到数据库的 Document
表中,然后保存它。
从数据库检索文件的该方法更简单
private byte[] LoadImage(int id, out string type)
{
byte[] fileBytes = null;
string fileType = null;
using (DocumentEntities databaseContext = new DocumentEntities())
{
var databaseDocument = databaseContext.Documents.FirstOrDefault(doc => doc.DocumentId == id);
if (databaseDocument != null)
{
fileBytes = databaseDocument.FileContent;
fileType = databaseDocument.Type;
}
}
type = fileType;
return fileBytes;
}
创建数据库上下文的实例,并获取 DocumentId
与请求的文档 ID 匹配的第一个文档。如果找到文档,则返回文档的字节(其内容)和文件类型。
关注点
这里没有什么特别的,但请注意,我在主控制器的 Index 视图中添加了一些 JavaScript。
$(document).ready(function () {
$("#preview").fadeOut(15);
$("#refreshButton").click(function () {
var imageToLoad = $("#imageId").val();
if (imageToLoad.length > 0) {
$("#preview").attr("src", "/Document/Show/" + imageToLoad);
$("#preview").fadeIn();
}
});
});
这个小程序使我们能够从数据库检索文档并将其显示为图像。HTML 显示一个文本框和一个按钮,在文本框中输入文档的数据库 ID,然后按按钮显示图像。
ASP.NET WebForms 项目使用完全相同的 JavaScript,但地址不同。
$(document).ready(function () {
$("#preview").fadeOut(15);
$("#refreshButton").click(function () {
var imageToLoad = $("#imageId").val();
if (imageToLoad.length > 0) {
$("#preview").attr("src", "/Download.ashx?id=" + imageToLoad);
$("#preview").fadeIn();
}
});
});
下载说明
请注意,该项目使用了一些 NuGet 包。包的名称(和版本)存储在 [UsedPackages.txt] 中。此外,请不要忘记更改两个 Web 项目的 web.config 中的 connectionstring
设置。
zip 文件还包含一个名为 [CreateDocumentsTable.sql] 的文件,这是一个 SQL 脚本,您可以在 SQL Server 数据库上运行它。它将在我文章中使用的数据库中创建 Documents
表。
历史
在此处保持您所做的任何更改或改进的实时更新。
- 2013/09/25 - 第一个版本 - 哇!太棒了
- 2013/09/30 - 添加了 ASP.NET 源代码和下载说明
- 2013/10/02 - 将创建数据库表的 SQL 脚本添加到源代码和文章中,并更改了标题
- 2013/10/07 - 添加了 ASP.NET WebForms 项目的描述