如何从MVC中的数据库中检索图像?

时间:2016-10-04 13:27:14

标签: c# asp.net-mvc varbinary

我一直在研究一个系统,允许我们的用户将图像上传到数据库中。将图像上传到数据库似乎工作正常,但我似乎无法将图像恢复出来并显示在我的视图中。我没有收到图片根本无法显示的任何错误消息。到目前为止,这是我的代码。

控制器 /创建方法

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(UserAccount userAccount, HttpPostedFileBase upload)
    {
        try
        {
            if (ModelState.IsValid)
            {
                if (upload != null && upload.ContentLength > 0)
                {
                    var photo = new UserImage
                    {
                        FileName = System.IO.Path.GetFileName(upload.FileName),
                        FileType = FileType.VesselImage,
                        ContentType = upload.ContentType
                    };
                    using (var reader = new System.IO.BinaryReader(upload.InputStream))
                    {
                        photo.Content = reader.ReadBytes(upload.ContentLength);
                    }
                    userAccount.UserImages = new List<UserImage> { photo };
                }
                db.UserAccounts.Add(userAccount);
                db.SaveChanges();
                return RedirectToAction("Index");
            }//if
        }//try
        catch (RetryLimitExceededException /* dex */) 
        {
            //Log the error (uncomment dex variable name and add a line here to write a log.
            ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
        }
        return View(userAccount);
    }

控制器 /详细信息方法 断点显示在此阶段找到并选择了图像。

    public ActionResult Details(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        UserAccount userAccount = db.UserAccounts
            .Include(s => s.UserImages)
            .SingleOrDefault(s => s.userId == id);
        if (userAccount == null)
        {
            return HttpNotFound();
        }
        return View(userAccount);
    }      

查看 /详情

@model Multiple_Table_Post.Models.UserAccount
@{
    ViewBag.Title = "Details";
}

<h2>Details</h2>
<div>
<h4>UserAccount</h4>
<hr />
<dl class="dl-horizontal">
    <dt>
        @Html.DisplayNameFor(model => model.userName)
    </dt>

    <dd>
        @Html.DisplayFor(model => model.userName)
    </dd>

    <dt>
        @Html.DisplayNameFor(model => model.userLocation)
    </dt>

    <dd>
        @Html.DisplayFor(model => model.userLocation)
    </dd>


    @if (Model.UserImages.Any(f => f.FileType == FileType.VesselImage))
    {
        <dt>
            Image
        </dt>
        <dd>
            <img src="~/File?id=@Model.UserImages.First(f => f.FileType == FileType.VesselImage).FileId" alt="avatar" />
        </dd>
    }

</dl>
</div>
<p>
@Html.ActionLink("Edit", "Edit", new { id = Model.userId }) |
@Html.ActionLink("Back to List", "Index")
</p>

我认为我的情况出了问题:

@if (Model.UserImages.Any(f => f.FileType == FileType.VesselImage))
    {
        <dt>
            Image
        </dt>
        <dd>
            <img src="~/File?id=@Model.UserImages.First(f => f.FileType == FileType.VesselImage).FileId" alt="avatar" />
        </dd>
    }

如果我在视图中的这一点处断开,我可以看到图像被选中但是注意到是输出。我什么都不回报。

我也包括了我的模型,希望我能解决这个问题的根源。他们在这里:

型号 / UserAccount

namespace Multiple_Table_Post.Models
{
using System;
using System.Collections.Generic;

public partial class UserAccount
{        

    public int userId { get; set; }
    public string userName { get; set; }
    public string userLocation { get; set; }


    public virtual ICollection<UserImage> UserImages { get; set; }
}
}

模型 / UserImage     命名空间Multiple_Table_Post.Models     {     使用系统;     使用System.Collections.Generic;

public partial class UserImage
{
    public int FileId { get; set; }
    public string FileName { get; set; }
    public string ContentType { get; set; }
    public byte[] Content { get; set; }
    public Nullable<int> PersonId { get; set; }
    public FileType FileType { get; set; }

    public virtual UserAccount UserAccount { get; set; }
}
}

模型 / FileType

namespace Multiple_Table_Post.Models
{
public enum FileType
{
    VesselImage = 1, Photo
}
}

谢谢,如果我错过了任何可以让这更容易的事情,请告诉我。

更新:在这里,我已经包含了断点信息,该信息是关于条件被命中时系统正在做什么以及数据可以看到的。

Condition is reached and the system knows there is an image in there enter image description here

3 个答案:

答案 0 :(得分:1)

我更喜欢这样做的方法是创建一个ActionResult,它直接为浏览器对图像的请求提供服务。这种方法的一个优点是,如果页面不止一次包含图像,浏览器将自动共享资源。这样可以节省数据库命中,数据传输并最大化缓存机会。

public ActionResult Portrait(int id)
{
    vPhotos p = sdb.vPhotos.Where(e => e.ID == id).SingleOrDefault();
    byte[] photoArray = new byte[] { };
    return File(smallPhotoArray, "image/png");
}

现在在您看来,只需将ActionMethod称为img src参考:

<img src="@Url.Action("Portrait", "MyController" , new { id = id })" />

答案 1 :(得分:0)

试试这个:

<img src="data:image/jpg;base64,[byte array]"/>

替换:

  1. jpg具有图片类型,即FileType
  2. [byte array]包含您的字节数组Content
  3. 如果尚未将Content转换为base64,则需要将其转换为

答案 2 :(得分:0)

好的,我一直在玩一点,并注意到我发布的更新中的一些内容。在下图中: enter image description here 您会注意到FileType列为0,但在FileType类中我告诉它FileType为1。

Data![shiftdate].Value = Date1

因此无法满足条件,因为它无法看到等于0的FileType。在FileType类中将VesselImage更改为0可以解决问题。 :)