仅更新其他字段后图像文件设置为空
Image File sets to null after updating only other fields
我有一个奇怪的功能,当我只更新图像以外的其他字段时,其他字段(FirstName
,LastName
)更新成功但随后图像将其自身设置为空,但是当我针对其他字段 (FirstName
、LastName
) 选择它时,它会成功更新。所以我想要的是当我不更新图像时它保持原样而不将其自身设置为 null。
这是我的 New.cshtm
文件,它处理创建和编辑数据:
<form asp-action="New" method="Post" asp-controller="Student" enctype="multipart/form-data">
<div asp-validation-summary="All"></div>
<input asp-for="Id" type="hidden"/>
<input name="IsEditMode" id="IsEditMode" value="@ViewBag.IsEditMode" type="hidden"/>
<div class="form-row">
<label>Upload Photo</label>
<input asp-for="ImageUrl" type="file" id="file" name="file" class="form-control"/>
</div>
<div class="form-row">
<div class="col">
<label asp-for="FirstName"></label>
<input asp-for="FirstName" class="form-control"/>
<span asp-validation-for="FirstName" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="MiddleName"></label>
<input asp-for="MiddleName" class="form-control"/>
<span asp-validation-for="MiddleName" class="text-danger"></span>
</div>
</div>
</form>
然后这些是我的 控制器 Student.cs
用于更新字段的方法:
public IActionResult New(Student student, string IsEditMode, IFormFile file)
{
if (!ModelState.IsValid)
{
ViewBag.IsEditMode = IsEditMode;
return View(student);
}
try
{
if (IsEditMode.Equals("false"))
{
_studentRepository.Create(student);
UploadFile(file, student.Id);
_toastNotification.AddSuccessToastMessage("Student has been created successfully.");
}
else
{
_studentRepository.Edit(student);
UploadFile(file, student.Id);
_toastNotification.AddSuccessToastMessage("Student has been edited successfully.");
}
return RedirectToAction(nameof(Index));
}
catch (Exception e)
{
return RedirectToAction(nameof(Index));
}
}
public IActionResult Edit(int id)
{
try
{
ViewBag.IsEditMode = "true";
var student = _studentRepository.GetSingleStudent(id);
return View("New", student);
}
catch (Exception ex)
{
return Content("Could not find Pet");
}
}
public void UploadFile(IFormFile file, long studentId)
{
var fileName = file.FileName;
var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/images",fileName);
using (var fileStream = new FileStream(path, FileMode.Create))
{
file.CopyTo(fileStream);
}
var student = _studentRepository.GetSingleStudent(studentId);
student.ImageUrl = fileName;
_studentRepository.Edit(student);
}
那么,这就是我在 存储库 中更新的方式:
然后在我的 Repository 中,这就是我更新字段的方式“:
public void Edit(Student student)
{
var existingStudent = _context.Students
.FirstOrDefault(s => s.Id == student.Id);
if (existingStudent != null)
{
// updating student.
_context.Entry(existingStudent).CurrentValues.SetValues(student);
_context.Entry(existingStudent).State = EntityState.Modified;
}
}
Index.cshtml
,这是一个列表图像和名字和姓氏以及 (操作按钮) Edit
、Delete
按钮:
<table class="table table-striped">
<thead class="thead-dark">
<tr>
<td ><b>Student Picture</b></td>
<td><b>FirstName</b></td>
<td><b>LastName</b></td>
<td colspan="2"> <b>Actions</b></td>
</tr>
</thead>
<tbody>
@foreach (var student in Model)
{
<tr>
<td>@student.StudentRegNo</td>
<td>
<div class="thumbnail">
<img src="/images/@student.ImageUrl" width="90" height="90"/>
</div>
</td>
<td>@student.FirstName</td>
<td>@student.LastName</td>
<d>
<td>
<a class="btn btn-warning" asp-action="Details" asp-controller="Student" asp-route-Id="@student.Id">Details</a>
</td>
<td>
<a class="btn btn-primary" asp-action="edit" asp-route-Id="@student.Id">Edit</a>
</td>
<td>
<a
class="btn btn-danger delete"
asp-route-Id="@student.Id"
asp-action="Delete">
Delete
</a>
</td>
</d>
</tr>
}
</tbody>
</table>
编辑
这是根据@Raul 解决方案的当前逻辑,但它不起作用:
if (student.ImageUrl != null)
{
_context.Entry(existingStudent).CurrentValues.SetValues(student);
_context.Entry(existingStudent).State = EntityState.Modified;
}
else
{
_context.Entry(existingStudent).Property(x => x.ImageUrl).IsModified = false;
_context.Entry(existingStudent).CurrentValues.SetValues(student);
_context.Entry(existingStudent).State = EntityState.Modified;
}
在您的 Edit
学生方法中,您可以将 ImageUrl Property
的 IsModified
设置为 false,这不会更新数据库中的图像字段:
public void Edit(Student student)
{
var existingStudent = _context.Students.FirstOrDefault(s => s.Id == student.Id);
if (existingStudent != null)
{
// updating student.
_context.Student.Attach(existingStudent);
_context.Entry(existingStudent).State = EntityState.Modified;
_context.Entry(existingStudent).Property(x => x.ImageUrl).IsModified=false;
_context.SaveChanges();
}
}
当然,您需要在此检查您的 ImageUrl
逻辑。如果您获得新图像,则相应地更新您的模型。
编辑:
您可以这样合并您的 if-else 条件:
if (student.ImageUrl != null)
{
_context.Student.Add(existingStudent);
_context.Entry(existingStudent).State EntityState.Modified;
//_context.Student.Update(existingStudent); //You can also use this. Comment out the upper two lines
_context.SaveChanges();
}
else
{
// updating student.
_context.Student.Attach(existingStudent);
_context.Entry(existingStudent).State = EntityState.Modified;
_context.Entry(existingStudent).Property(x => x.ImageUrl).IsModified=false;
_context.SaveChanges();
}
可以考虑这两种情况separately.When只更新字段不更新图片,文件为null,那么需要将现有学生的ImageUrl关联到发布的学生。
//...
try
{
if (IsEditMode.Equals("false"))
{
_studentRepository.Create(student);
UploadFile(file, student.Id);
_toastNotification.AddSuccessToastMessage("Student has been created successfully.");
}
else
{
//edit mode
if(file == null)//Updating fields without updating the image.
{
var existingStudent = _context.Students.FirstOrDefault(s => s.Id == student.Id);
if (existingStudent != null)
{
// updating student with previousImageUrl
student.ImageUrl = existingStudent.ImageUrl;
_context.Entry(existingStudent).CurrentValues.SetValues(student);
_context.Entry(existingStudent).State = EntityState.Modified;
_context.SaveChanges();
}
}
else//Updating the fields and the image
{
_studentRepository.Edit(student);
UploadFile(file, student.Id);
}
_toastNotification.AddSuccessToastMessage("Student has been edited successfully.");
}
return RedirectToAction(nameof(Index));
}
catch (Exception e)
{
return RedirectToAction(nameof(Index));
}
}
public void UploadFile(IFormFile file, long studentId)
{
var fileName = file.FileName;
var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/images", fileName);
using (var fileStream = new FileStream(path, FileMode.Create))
{
file.CopyTo(fileStream);
}
var student = _studentRepository.GetSingleStudent(studentId);
student.ImageUrl = fileName;
_studentRepository.Edit(student);
}
public void Edit(Student student)
{
var existingStudent = _context.Students
.FirstOrDefault(s => s.Id == student.Id);
if (existingStudent != null)
{
// updating student.
_context.Entry(existingStudent).CurrentValues.SetValues(student);
_context.Entry(existingStudent).State = EntityState.Modified;
_context.SaveChanges();
}
}
我有一个奇怪的功能,当我只更新图像以外的其他字段时,其他字段(FirstName
,LastName
)更新成功但随后图像将其自身设置为空,但是当我针对其他字段 (FirstName
、LastName
) 选择它时,它会成功更新。所以我想要的是当我不更新图像时它保持原样而不将其自身设置为 null。
这是我的 New.cshtm
文件,它处理创建和编辑数据:
<form asp-action="New" method="Post" asp-controller="Student" enctype="multipart/form-data">
<div asp-validation-summary="All"></div>
<input asp-for="Id" type="hidden"/>
<input name="IsEditMode" id="IsEditMode" value="@ViewBag.IsEditMode" type="hidden"/>
<div class="form-row">
<label>Upload Photo</label>
<input asp-for="ImageUrl" type="file" id="file" name="file" class="form-control"/>
</div>
<div class="form-row">
<div class="col">
<label asp-for="FirstName"></label>
<input asp-for="FirstName" class="form-control"/>
<span asp-validation-for="FirstName" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="MiddleName"></label>
<input asp-for="MiddleName" class="form-control"/>
<span asp-validation-for="MiddleName" class="text-danger"></span>
</div>
</div>
</form>
然后这些是我的 控制器 Student.cs
用于更新字段的方法:
public IActionResult New(Student student, string IsEditMode, IFormFile file)
{
if (!ModelState.IsValid)
{
ViewBag.IsEditMode = IsEditMode;
return View(student);
}
try
{
if (IsEditMode.Equals("false"))
{
_studentRepository.Create(student);
UploadFile(file, student.Id);
_toastNotification.AddSuccessToastMessage("Student has been created successfully.");
}
else
{
_studentRepository.Edit(student);
UploadFile(file, student.Id);
_toastNotification.AddSuccessToastMessage("Student has been edited successfully.");
}
return RedirectToAction(nameof(Index));
}
catch (Exception e)
{
return RedirectToAction(nameof(Index));
}
}
public IActionResult Edit(int id)
{
try
{
ViewBag.IsEditMode = "true";
var student = _studentRepository.GetSingleStudent(id);
return View("New", student);
}
catch (Exception ex)
{
return Content("Could not find Pet");
}
}
public void UploadFile(IFormFile file, long studentId)
{
var fileName = file.FileName;
var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/images",fileName);
using (var fileStream = new FileStream(path, FileMode.Create))
{
file.CopyTo(fileStream);
}
var student = _studentRepository.GetSingleStudent(studentId);
student.ImageUrl = fileName;
_studentRepository.Edit(student);
}
那么,这就是我在 存储库 中更新的方式:
然后在我的 Repository 中,这就是我更新字段的方式“:
public void Edit(Student student)
{
var existingStudent = _context.Students
.FirstOrDefault(s => s.Id == student.Id);
if (existingStudent != null)
{
// updating student.
_context.Entry(existingStudent).CurrentValues.SetValues(student);
_context.Entry(existingStudent).State = EntityState.Modified;
}
}
Index.cshtml
,这是一个列表图像和名字和姓氏以及 (操作按钮) Edit
、Delete
按钮:
<table class="table table-striped">
<thead class="thead-dark">
<tr>
<td ><b>Student Picture</b></td>
<td><b>FirstName</b></td>
<td><b>LastName</b></td>
<td colspan="2"> <b>Actions</b></td>
</tr>
</thead>
<tbody>
@foreach (var student in Model)
{
<tr>
<td>@student.StudentRegNo</td>
<td>
<div class="thumbnail">
<img src="/images/@student.ImageUrl" width="90" height="90"/>
</div>
</td>
<td>@student.FirstName</td>
<td>@student.LastName</td>
<d>
<td>
<a class="btn btn-warning" asp-action="Details" asp-controller="Student" asp-route-Id="@student.Id">Details</a>
</td>
<td>
<a class="btn btn-primary" asp-action="edit" asp-route-Id="@student.Id">Edit</a>
</td>
<td>
<a
class="btn btn-danger delete"
asp-route-Id="@student.Id"
asp-action="Delete">
Delete
</a>
</td>
</d>
</tr>
}
</tbody>
</table>
编辑
这是根据@Raul 解决方案的当前逻辑,但它不起作用:
if (student.ImageUrl != null)
{
_context.Entry(existingStudent).CurrentValues.SetValues(student);
_context.Entry(existingStudent).State = EntityState.Modified;
}
else
{
_context.Entry(existingStudent).Property(x => x.ImageUrl).IsModified = false;
_context.Entry(existingStudent).CurrentValues.SetValues(student);
_context.Entry(existingStudent).State = EntityState.Modified;
}
在您的 Edit
学生方法中,您可以将 ImageUrl Property
的 IsModified
设置为 false,这不会更新数据库中的图像字段:
public void Edit(Student student)
{
var existingStudent = _context.Students.FirstOrDefault(s => s.Id == student.Id);
if (existingStudent != null)
{
// updating student.
_context.Student.Attach(existingStudent);
_context.Entry(existingStudent).State = EntityState.Modified;
_context.Entry(existingStudent).Property(x => x.ImageUrl).IsModified=false;
_context.SaveChanges();
}
}
当然,您需要在此检查您的 ImageUrl
逻辑。如果您获得新图像,则相应地更新您的模型。
编辑:
您可以这样合并您的 if-else 条件:
if (student.ImageUrl != null)
{
_context.Student.Add(existingStudent);
_context.Entry(existingStudent).State EntityState.Modified;
//_context.Student.Update(existingStudent); //You can also use this. Comment out the upper two lines
_context.SaveChanges();
}
else
{
// updating student.
_context.Student.Attach(existingStudent);
_context.Entry(existingStudent).State = EntityState.Modified;
_context.Entry(existingStudent).Property(x => x.ImageUrl).IsModified=false;
_context.SaveChanges();
}
可以考虑这两种情况separately.When只更新字段不更新图片,文件为null,那么需要将现有学生的ImageUrl关联到发布的学生。
//...
try
{
if (IsEditMode.Equals("false"))
{
_studentRepository.Create(student);
UploadFile(file, student.Id);
_toastNotification.AddSuccessToastMessage("Student has been created successfully.");
}
else
{
//edit mode
if(file == null)//Updating fields without updating the image.
{
var existingStudent = _context.Students.FirstOrDefault(s => s.Id == student.Id);
if (existingStudent != null)
{
// updating student with previousImageUrl
student.ImageUrl = existingStudent.ImageUrl;
_context.Entry(existingStudent).CurrentValues.SetValues(student);
_context.Entry(existingStudent).State = EntityState.Modified;
_context.SaveChanges();
}
}
else//Updating the fields and the image
{
_studentRepository.Edit(student);
UploadFile(file, student.Id);
}
_toastNotification.AddSuccessToastMessage("Student has been edited successfully.");
}
return RedirectToAction(nameof(Index));
}
catch (Exception e)
{
return RedirectToAction(nameof(Index));
}
}
public void UploadFile(IFormFile file, long studentId)
{
var fileName = file.FileName;
var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/images", fileName);
using (var fileStream = new FileStream(path, FileMode.Create))
{
file.CopyTo(fileStream);
}
var student = _studentRepository.GetSingleStudent(studentId);
student.ImageUrl = fileName;
_studentRepository.Edit(student);
}
public void Edit(Student student)
{
var existingStudent = _context.Students
.FirstOrDefault(s => s.Id == student.Id);
if (existingStudent != null)
{
// updating student.
_context.Entry(existingStudent).CurrentValues.SetValues(student);
_context.Entry(existingStudent).State = EntityState.Modified;
_context.SaveChanges();
}
}