65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.55/5 (35投票s)

2013年9月25日

CPOL

4分钟阅读

viewsIcon

141723

downloadIcon

5072

一个关于在 SQL Server 中存储图像并在 ASP.NET 网站上显示图像的快速教程

引言

这篇文章实际上是源于论坛上对这个主题知识的需求。关于如何将二进制数据(图像)存储在 SQL Server 数据库中以及如何检索它们,甚至如何使用 ASP.NET (MVC) 将图像返回以在网站上显示的问题。对于 ASP.NET WebForms 开发者,我也包含了一个 ASP.NET WebForms 示例项目。

背景

该解决方案包含两个演示项目。一个 ASP.NET WebForms 项目和一个 ASP.NET MVC 4 项目。MVC 演示项目包含两个控制器。一个 HomeController 和一个 DocumentControllerDocumentController 包含两个上传和下载图像的操作方法。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 项目的描述
© . All rights reserved.