如何将图像从 ASP.net MVC 上传到数据库中的 VARBINARY

How to upload an image from ASP.net MVC to VARBINARY in a database

我已经尝试了一段时间,试图让我的项目接受图像文件并将它们提交到我的数据库,但无济于事。我看到的一切都已有 10 多年历史,不再有效。 这只是 MVC 的基本编辑视图,我只是加强了安全性。

public async Task<IActionResult> Edit([Bind("UserId,Name,Email,Password,Type,EmailConfirm,Pfp")] UserIdentity userIdentity)
        {
            //check if user is logged in for this action
            if (HttpContext.Session.GetInt32("sessionUserID") == null || HttpContext.Session.GetInt32("sessionUserID") <= 0)
            {
                ViewBag.reasonFailed = "You need to log in before doing this!";
                return View("Failed");
            }

            //for use in LINQ queries
            MySchoolDataContext dbContext = new();

            //checks if the user is an admin
            if ((from user in dbContext.UserIdentities where user.UserId == userIdentity.UserId select user.Type).FirstOrDefault().Equals("A"))
            {
                
            }
            else
            {

                //Checking if the userID matches the id in the URL
                if (HttpContext.Session.GetInt32("sessionUserID") != userIdentity.UserId)
                {
                    ViewBag.reasonFailed = "You cannot edit an account that isn't your own!";
                    return View("Failed");
                }

                //checks if the email is confirmed
                if ((from user in dbContext.UserIdentities where user.UserId == HttpContext.Session.GetInt32("sessionUserID") select user.EmailConfirm).FirstOrDefault().Equals("n"))
                {
                    return RedirectToAction("confirmEmail");
                }
            }

            if (userIdentity.UserId != userIdentity.UserId)
            {
                return NotFound();
            }

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(userIdentity);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!UserIdentityExists(userIdentity.UserId))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }
            return View(userIdentity);
        }

我正在使用的视图:

@model Rideshare.Models.UserIdentity

@{
    ViewData["Title"] = "Edit";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>Edit</h1>

<h4>UserIdentity</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="UserId" />
            <div class="form-group">
                <label asp-for="Name" class="control-label"></label>
                <input asp-for="Name" class="form-control" />
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Email" class="control-label"></label>
                <input asp-for="Email" class="form-control" />
                <span asp-validation-for="Email" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Password" class="control-label"></label>
                <input asp-for="Password" class="form-control" />
                <span asp-validation-for="Password" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Type" class="control-label"></label>
                <input asp-for="Type" class="form-control" />
                <span asp-validation-for="Type" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="EmailConfirm" class="control-label"></label>
                <input asp-for="EmailConfirm" class="form-control" />
                <span asp-validation-for="EmailConfirm" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Pfp" class="control-label"></label>
                <input asp-for="Pfp" type="file" class="form-control" />
                <span asp-validation-for="Pfp" class="text-danger"></span>
            </div>

            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

感谢您提供的任何帮助。这是一个学校项目,连我的教授都不知道如何完成。我问过。

编辑:有人问我正在使用的模型,所以在这里。

using System;
using System.Collections.Generic;

#nullable disable

namespace Rideshare.Models
{
    public partial class UserIdentity
    {
        public UserIdentity()
        {
            HistoryDrivers = new HashSet<History>();
            HistoryPasses = new HashSet<History>();
            RatingRaters = new HashSet<Rating>();
            RatingUsers = new HashSet<Rating>();
        }

        public int UserId { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public string Password { get; set; }
        public string Type { get; set; }
        public string EmailConfirm { get; set; }
        public byte[] Pfp { get; set; }

        public virtual ICollection<History> HistoryDrivers { get; set; }
        public virtual ICollection<History> HistoryPasses { get; set; }
        public virtual ICollection<Rating> RatingRaters { get; set; }
        public virtual ICollection<Rating> RatingUsers { get; set; }
    }
}

我正在彻底改变它,因为我在将图像转换为字节数组的过程中犯了一点错误。实际上有一个非常简单的方法可以做到这一点!它只是花了很多谷歌搜索和兔子洞(也是我的老师!)。我只是使用了 MemoryStreamIFormFile 因为你可以直接从一个转换到另一个。

        public async Task<IActionResult> ChangePfp(IFormFile theFile, [Bind("UserId,Name,Email,Password,Type,EmailConfirm,Pfp")] UserIdentity userIdentity)
        {
            //check file length just in case of null
            if (theFile.Length > 0)
            {
                //converting the image(file) to a byte array(MemoryStream)
                using (MemoryStream mStream = new())
                {
                    theFile.CopyTo(mStream);
                    userIdentity.Pfp = mStream.ToArray();
                }
            }
            else
            {
                return View();
            }

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(userIdentity);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!UserIdentityExists(userIdentity.UserId))
                    {
                        ViewBag.reasonFailed = "Not found";
                        return View("Failed");
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }
            return View(userIdentity);
        }

这是我用来执行此操作的代码,但删除了大部分代码以使其更易于阅读并将其中一些设为私有。真的就是这么简单。要在视图中将其转换回,您所要做的就是在您想要的视图中进行此操作:

@if (Model.Pfp != null)
            {
            <img src="data:image/jpeg;base64,@(Convert.ToBase64String(Model.Pfp))"/>
            }

感谢所有试图提供帮助的人!