【问题标题】:Incorrect upload multiple images in Edit method在 Edit 方法中上传多张图片不正确
【发布时间】:2017-02-26 08:17:30
【问题描述】:

我有方法 Edit 将主页的一张图片和画廊的多张图片上传到数据库中的现有记录。我有一对多的关系表(FurnitureImages 我存储有关图像的信息),我也使用 View Model 所以这里是我的代码

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(FurnitureVM model)
{
    if (model.MainFile != null && model.MainFile.ContentLength > 0)
    {
        string displayName = model.MainFile.FileName;
        string extension = Path.GetExtension(displayName);
        string fileName = string.Format("{0}{1}", Guid.NewGuid(), extension);
        string path = "~/Upload/" + fileName;
        model.MainFile.SaveAs(Server.MapPath( path));
        model.MainImage = new ImageVM() { Path = path, DisplayName = displayName };
    }     
    foreach (HttpPostedFileBase file in model.SecondaryFiles)
    {
        FurnitureImages images = new FurnitureImages();
        if (file != null && file.ContentLength > 0)
        {
            string displayName = file.FileName;
            string extension = Path.GetExtension(displayName);
            string fileName = string.Format("{0}{1}", Guid.NewGuid(), extension);
            var path = "~/Upload/" + fileName;
            file.SaveAs(Server.MapPath(path));
            model.SecondaryImages = new List<ImageVM> { new ImageVM { DisplayName = displayName, Path = path } };
        }
    }
    if (!ModelState.IsValid)
    {
        model.CategoryList = new SelectList(db.Categories, "CategoryId", "Name",model.CategoryId); // repopulate the SelectList
        return View(model);
    }

    Furniture furniture = db.Furnitures.Where(x => x.FurnitureId == model.ID).FirstOrDefault();
    FurnitureImages main = furniture.Images.Where(x => x.IsMainImage).FirstOrDefault();
    furniture.Name = model.Name;
    furniture.Description = model.Description;
    furniture.Manufacturer = model.Manufacturer;
    furniture.Price = model.Price;
    furniture.CategoryId = model.CategoryId;
    furniture.Size = model.Size;       
    main.DisplayName = model.MainImage.DisplayName;
    main.Path = model.MainImage.Path;
    main.IsMainImage = model.MainImage.IsMainImage;
    if (model.MainImage != null && !model.MainImage.Id.HasValue)
    {
        FurnitureImages image = new FurnitureImages
        {
            Path = model.MainImage.Path,
            DisplayName = model.MainImage.DisplayName,
            IsMainImage = true
        };
        furniture.Images.Add(image);
        db.Entry(furniture).State = EntityState.Modified;
    } 
    // Update secondary images
    IEnumerable<ImageVM> newImages = model.SecondaryImages.Where(x => x.Id == null);
    foreach (ImageVM image in newImages)
    {
        FurnitureImages images = new FurnitureImages
        {
            DisplayName = image.DisplayName,
            Path =  image.Path , 
            IsMainImage = false
        };
        furniture.Images.Add(images);
    }
    ViewBag.CategoryId = new SelectList(db.Categories, "CategoryId", "Name", furniture.CategoryId);
    db.SaveChanges();
    return RedirectToAction("Index");
}

主图像上传良好,但是当我尝试从另一个输入文件上传多个图像时

@Html.TextBoxFor(m => m.SecondaryFiles, new { type = "file", multiple = "multiple" , name = "SecondaryFiles" })
@Html.ValidationMessageFor(m => m.SecondaryFiles)
@for (int i = 0; i < Model.SecondaryImages.Count; i++)
{
    @Html.HiddenFor(m => m.SecondaryImages[i].Id)
    @Html.HiddenFor(m => m.SecondaryImages[i].Path)
    @Html.HiddenFor(m => m.SecondaryImages[i].DisplayName)
    <img src="@Url.Content(Model.SecondaryImages[i].Path)" />
}

它只上传一张图片,尽管我一直尝试上传许多图片,但它总是只上传一张,那么我的方法哪里出错了?

【问题讨论】:

  • db.SaveChanges();之前立即致电db.Entry(furniture).State = EntityState.Modified;
  • @StephenMuecke 我试过了,有问题,只上传 1 张图片,当我选择 2 个或更多时
  • 你的意思是当你选择更多SecondaryImages时它只上传一个? (您是指上传(将文件保存到磁盘)还是将项目保存到FurnitureImages 表中的数据库?)
  • 您的代码还有一些其他问题 - 但您所指的是由您的 model.SecondaryImages = new List&lt;ImageVM&gt; { new ImageVM { DisplayName = displayName, Path = path } }; 引起的 - 您不断覆盖集合。它需要在循环内为model.SecondaryImages.Add(new ImageVM { ... })
  • @StephenMuecke 是的,我的意思是当我选择更多时它只上传一个 SecondaryImages 。在我的逻辑中,当我上传图像时,它会上传到文件系统中的文件夹以及有关图像创建和存储在数据库中的信息,我尝试添加 EntityState.Added 但出现错误

标签: c# asp.net asp.net-mvc


【解决方案1】:

您的问题是在第一个 foreach 循环中,您正确地将每个文件保存到服务器,但在每次迭代中,您创建一个新的 List&lt;ImageVM&gt; 并覆盖 SecondaryImages 的值,所以当循环完成时,它只包含一个项目(基于最后一张图片)。

将循环改为

foreach (HttpPostedFileBase file in model.SecondaryFiles)
{
    // FurnitureImages images = new FurnitureImages(); -- DELETE
    if (file != null && file.ContentLength > 0)
    {
        string displayName = file.FileName;
        string extension = Path.GetExtension(displayName);
        string fileName = string.Format("{0}{1}", Guid.NewGuid(), extension);
        var path = "~/Upload/" + fileName;
        file.SaveAs(Server.MapPath(path));
        // Add a new ImageVM to the collection 
        model.SecondaryImages.Add(new ImageVM { DisplayName = displayName, Path = path });
    }
}

请注意,以上假设您的视图模型具有初始化SecondaryImages 的无参数构造函数。如果没有,则在循环前添加model.SecondaryImages = new List&lt;ImageVM&gt;

需要解决的其他一些小问题。

  1. 生成SelectList的代码应该是 model.CategoryList = new SelectList(db.Categories, "CategoryId", "Name"); - SelectList 构造函数的最后一个参数是 绑定到模型属性时被忽略,因此毫无意义。
  2. 删除ViewBag.CategoryId = new SelectList(...) 代码行。 您的模型已经包含 SelectList 的属性(根据 注意1)但无论如何,你的重定向,所以添加任何东西 ViewBag 毫无意义。
  3. 移动您的db.Entry(furniture).State = EntityState.Modified;db.SaveChanges(); 之前的代码

【讨论】:

    猜你喜欢
    • 2016-11-22
    • 1970-01-01
    • 2019-11-13
    • 2019-11-15
    • 1970-01-01
    相关资源
    最近更新 更多