【问题标题】:How to keep the existing image if no new image selected?如果没有选择新图像,如何保留现有图像?
【发布时间】:2020-09-13 12:01:57
【问题描述】:

我知道有类似的问题。但是我花了一整天都无法解决我的问题,因为我完全是菜鸟。因此,如果有人为我的 ASP.Net Core 项目提供特定的解决方案,我将不胜感激。

如果您需要更多信息,尽管问。

谢谢。


所以,我的项目是关于导演的:

public class Director
{
    public Director()
    {
        Movies = new List<Movie>();
    }
    public int DirectorId { get; set; }
    [Required]
    public string Name { get; set; }
    public string Country { get; set; }
    public string Bio { get; set; }
    public List<Movie> Movies { get; set; }
    public string PhotoURL { get; set; } // This field holds only the name of the photo, Not its URL.
}

我的项目将图像保存在“wwwroot/uploads”中。每个导演都有一个形象。我可以从我的硬盘中为每个导演选择一个新图像。

问题:

我可以更新导演形象。但是如果我不选择新图像,现有图像将被删除。我想阻止它。如果我不选择新图像,我希望它保留现有图像。


Edit.cshtl.cs

public class EditModel : PageModel
{
    private readonly Context _context;
    private readonly IWebHostEnvironment hostingEnvironment;

    public EditModel(Context context, IWebHostEnvironment environment)
    {
        _context = context;
        this.hostingEnvironment = environment;
    }

    [BindProperty]
    public Director Director { get; set; }
    [BindProperty]
    public IFormFile Image { set; get; }
    public async Task<IActionResult> OnGetAsync(int? directorId)
    {
        if (directorId == null)
        {
            return NotFound();
        }

        Director = await _context.Director.FirstOrDefaultAsync(m => m.DirectorId == directorId);

        if (Director == null)
        {
            return NotFound();
        }
        return Page();
    }

    // To protect from overposting attacks, enable the specific properties you want to bind to, for
    // more details, see https://aka.ms/RazorPagesCRUD.
    public async Task<IActionResult> OnPostAsync(int? directorId)
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }

        if (this.Image != null)
        {
            var fileName = GetUniqueName(this.Image.FileName);
            var uploads = Path.Combine(hostingEnvironment.WebRootPath, "uploads");
            var filePath = Path.Combine(uploads, fileName);
            this.Image.CopyTo(new FileStream(filePath, FileMode.Create));
            this.Director.PhotoURL = fileName; // Set the file name
        }

        _context.Attach(Director).State = EntityState.Modified;
        try
        {
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!DirectorExists(Director.DirectorId))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return RedirectToPage("./Index");
    }

    private bool DirectorExists(int id)
    {
        return _context.Director.Any(e => e.DirectorId == id);
    }
    private string GetUniqueName(string fileName)
    {
        fileName = Path.GetFileName(fileName);
        return Path.GetFileNameWithoutExtension(fileName)
               + "_" + Guid.NewGuid().ToString().Substring(0, 4)
               + Path.GetExtension(fileName);
    }



}

编辑.cshtml

<form method="post" enctype="multipart/form-data">
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>

        <input type="hidden" asp-for="Director.DirectorId" />



        <div class="form-group">
            <label asp-for="Director.Name" class="control-label"></label>
            <input asp-for="Director.Name" class="form-control" />
            <span asp-validation-for="Director.Name" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Director.Country" class="control-label"></label>
            <input asp-for="Director.Country" class="form-control" />
            <span asp-validation-for="Director.Country" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Director.Bio" class="control-label"></label>
            <input asp-for="Director.Bio" class="form-control" />
            <span asp-validation-for="Director.Bio" class="text-danger"></span>
        </div>



        <div>
            <img id="blah" src="~/uploads/@Model.Director.PhotoURL" />
        </div>

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

        <div class="form-group" runat="server">
            <label asp-for="Director.PhotoURL" class="control-label"></label>
            <input type="file" asp-for="Image" class="form-control" id="imgInp" value="~/uploads/@Model.Director.PhotoURL" />
            <span asp-validation-for="Director.PhotoURL" class="text-danger"></span>
        </div>

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

    </form>

site.js:

function readURL(input) {
if (input.files && input.files[0]) {

    var reader = new FileReader();


    reader.onload = function (e) {
        $('#blah').attr('src', e.target.result);
    }

    reader.readAsDataURL(input.files[0]); // convert to base64 string
    }
}

$("#imgInp").change(function () {
    if ($('#imgInp').get(0).files.length !== 0) {

        readURL(this);
    }
});

编辑页面:

【问题讨论】:

    标签: javascript c# asp.net asp.net-core


    【解决方案1】:

    最简单的做法是在您的 OnPostAsync 调用中使用 else 子句:if (this.Image != null)

    由于您将上下文设置为已更改并进行更新,因此您正在将空值写入图像。使用else,您可以执行以下操作:

    else { this.Director.PhotoURL = LastImage; }

    至于如何获取 LastImage 的值,最简单的方法是使用传入的 DirectorId 通过 linq 查询拉取它(与上面获取 Director 对象的方式相同)。

    【讨论】:

      【解决方案2】:

      修改代码的最简单方法是获取数据库并将图像路径设置为原始图像路径(如果新图像路径为空)。不过,这确实有一个额外的数据库调用的缺点:

      if (this.Image != null)
      {
          ...
      }
      
      else
      {
          Director.PhotoURL = (await _context.Director.FirstOrDefaultAsync(m => m.DirectorId == directorId))?PhotoURL;
      }
      

      另一种选择是在您从数据库中检索原始图像路径时将其存储在某处,然后在新图像路径为空时使用它。这不会涉及额外的获取。你可以这样做:

      [BindProperty]
      public string OriginalImage { set; get; }
      
      ...
      
      OriginalImage = Director.PhotoURL
      
      ...
      
      <input type="hidden" asp-for="OriginalImage"/>
      
      ...
      
      if (this.Image != null)
      {
          ...
      }
      
      else
      {
          Director.PhotoURL = OriginalImage;
      }
      

      【讨论】:

      • 第二种解决方案对我有用,一点也不难。
      • 第一个解决方案是“?”要么 ”。”?曾是 ”?”错字?无论如何,我编辑了您的代码并替换了“?”带“.”,但出现此错误:InvalidOperationException: The instance of entity type 'Director' cannot be tracked because another instance with the same key value for {'DirectorId'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.
      猜你喜欢
      • 1970-01-01
      • 2019-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-08
      • 2022-10-12
      • 2015-11-18
      • 2012-11-21
      相关资源
      最近更新 更多