изображение сбрасывается при редактировании (обновлении) сообщения в ASP.NET - PullRequest
0 голосов
/ 07 апреля 2020

Я могу создать пост. Также доступно добавление изображения в пост. Но когда я редактирую пост позже, изображение удаляется, и мне приходится добавлять это изображение снова при каждом редактировании. Как я могу сделать так, чтобы изображение запомнилось навсегда, и оно будет изменено только в случае, если я добавлю новое?

AdminController.cs (отвечает за редактирование)

[HttpGet]
        public IActionResult EditPost(int? id)
        {
            if (id == null)
            {
                return View(new PostViewModel());
            }
            else
            {
                var post = _repo.GetPost((int)id);
                return View(new PostViewModel
                {
                    Id = post.Id,
                    Text = post.Text,
                });
            }
        }

[HttpPost]
   public async Task<IActionResult> EditPost(PostViewModel vm)
      {
         var post = new Post
         {
            Id = vm.Id,
            Text = vm.Text,
            Image = await _fileManager.SaveImage(vm.Image)
         };
         if (post.Id == 0)
            _repo.AddPost(post);
         else
            _repo.UpdatePost(post);
         if (await _repo.SaveChangesAsync())
            return RedirectToAction("Posts");
         else
            return View(post);
      }

Post.cs в моделях

namespace Project.Models
{
    public class Post
    {
        public int Id { get; set; }
        public string Text { get; set; } = "";
        public string Image { get; set; } = "";
    }
}

Repository.cs

public void UpdatePost(Post post)
        {
            _ctx.Post.Update(post);
        }

IRepository.cs

void UpdatePost(Post post);

На всякий случай я публикую sh PostController.cs

public IActionResult Index()
        {
            var posts = _repo.GetAllPosts();
            return View(posts);
        }

        public IActionResult Post(int id)
        {
            var post= _repo.GetPost(id);
            return View(post);
        }

        [HttpGet("/Image/{image}")]

        public IActionResult Image(string image)
        {
            var path = image.Substring(image.LastIndexOf('.') + 1);
            return new FileStreamResult(_fileManager.ImageStream(image), $"image/{path}");
        }

Ответы [ 2 ]

0 голосов
/ 07 апреля 2020

Это ожидаемое поведение. Загрузка файла не может быть установлена ​​сервером, потому что у сервера нет доступа к файловой системе клиента. Клиент должен всегда дать согласие на загрузку локального файла, и это согласие дается через диалоговое окно загрузки файла. Если клиент отправляется обратно в форму из-за ошибки проверки, он должен загрузить файл снова.

Теперь, несмотря на это, есть обходные пути, хотя ни один из них не идеален. Ввод файла может быть установлен вручную с помощью файла data (просто не ссылка на файловую систему) через JavaScript File API. Вы можете использовать File API для чтения данных файла после того, как пользователь выберет файл, сохранить его в localStorage (в браузере), а затем попытаться выполнить чтение из localStorage при загрузке страницы и установить для ввода файла эти данные файла, если есть присутствует ключ.

Однако localStorage имеет жесткое ограничение в 10 МБ, поэтому вам нужно быть осторожным, чтобы убедиться, что размер файла не превышает его, а также все, что уже может быть сохранено или также будет храниться там.

В качестве альтернативы, вы можете сохранить файловый сервер перед отправкой пользователя обратно, чтобы он оставался доступным после того, как он исправит свои записи и повторно отправит сообщение. Однако пользователь может полностью отказаться от формы или загрузить новый файл, поэтому вам потребуется стратегия для очистки этих временных файлов.

0 голосов
/ 07 апреля 2020

Вы можете следовать многим другим подходам для этого, но я буду ссылаться на два из них. Сначала вы можете перенести изображение на клиентскую часть, затем снова перенести его на сервер. Вы также должны отправить изображение на сервер.

[HttpGet]
    public IActionResult EditPost(int? id)
    {
        if (id == null)
        {
            return View(new PostViewModel());
        }
        else
        {
            var post = _repo.GetPost((int)id);
            return View(new PostViewModel
            {
                Id = post.Id,
                Text = post.Text,
                Image = post.Image
            });
        }
    }

И, во-вторых, вы можете обновить изображение, только когда imageUrl не пуст. Но это придет с новым условием «что если клиент захочет удалить изображение?». Вы должны решить, когда вы уверены, что именно хотите делать. Я добавляю какой-то незавершенный код, чтобы дать представление.

 [HttpPost]
public async Task<IActionResult> EditPost(PostViewModel vm)
{
  var post = new Post
  {
    Id = vm.Id,
    Text = vm.Text,
    Image = await _fileManager.SaveImage(vm.Image)
  };


  if (post.Id == 0)
    _repo.AddPost(post);
  else
  {
    if (vm.Image == null)
    {
      //Overwriting viewmodel's image property if empty with old record's image.
      var oldRecord = _repo.GetPost(vm.Id);
      post.Image = oldRecord?.Image;
    }
    _repo.UpdatePost(post);
  }

  if (await _repo.SaveChangesAsync())
    return RedirectToAction("Posts");
  else
    return View(post);
}
...