仅更新其他字段后图像文件设置为空

Image File sets to null after updating only other fields

我有一个奇怪的功能,当我只更新图像以外的其他字段时,其他字段(FirstNameLastName)更新成功但随后图像将其自身设置为空,但是当我针对其他字段 (FirstNameLastName) 选择它时,它会成功更新。所以我想要的是当我不更新图像时它保持原样而不将其自身设置为 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,这是一个列表图像和名字和姓氏以及 (操作按钮) EditDelete按钮:

<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 PropertyIsModified 设置为 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();
       }
    }