如何将图像从 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; }
}
}
我正在彻底改变它,因为我在将图像转换为字节数组的过程中犯了一点错误。实际上有一个非常简单的方法可以做到这一点!它只是花了很多谷歌搜索和兔子洞(也是我的老师!)。我只是使用了 MemoryStream
和 IFormFile
因为你可以直接从一个转换到另一个。
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))"/>
}
感谢所有试图提供帮助的人!
我已经尝试了一段时间,试图让我的项目接受图像文件并将它们提交到我的数据库,但无济于事。我看到的一切都已有 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; }
}
}
我正在彻底改变它,因为我在将图像转换为字节数组的过程中犯了一点错误。实际上有一个非常简单的方法可以做到这一点!它只是花了很多谷歌搜索和兔子洞(也是我的老师!)。我只是使用了 MemoryStream
和 IFormFile
因为你可以直接从一个转换到另一个。
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))"/>
}
感谢所有试图提供帮助的人!