提问人:RayViLOz 提问时间:11/2/2023 更新时间:11/2/2023 访问量:35
我想预填充 IFormFile 类型的输入
I want to pre-fill an input of type IFormFile
问:
我正在为一些具有 ImagePath 属性的产品做一个编辑页面。当我创建产品时,我使用 IFormFile 类型的输入将图像下载到网站的 /img/products 文件夹中,它工作得很好。这里是上下文:
[HttpPost]
public async Task<IActionResult> CreateProduct(AdminCreateProductVM vm)
{
if (!ModelState.IsValid)
return View(vm);
bool productAlreadyExists = _context.Products.Any(u => u.SKU == vm.SKU);
if (productAlreadyExists)
{
ModelState.AddModelError(string.Empty, "Un produit avec le même SKU existe déjà.");
return View(vm);
}
if (vm.Image is not null && vm.Image.Length > 0)
{
var webRootPath = _hostingEnvironment.WebRootPath;
var filePath = Path.Combine(webRootPath, "img/products", vm.SKU! + ".jpg");
using (var stream = new FileStream(filePath, FileMode.Create))
{
await vm.Image.CopyToAsync(stream);
}
}
else
{
ModelState.AddModelError(string.Empty, "Veuillez sélectionner une image.");
return View(vm);
}
var product = new Product()
{
SKU = vm.SKU,
Name = vm.Name,
Brand = vm.Brand,
Model = vm.Model,
ImagePath = "~/img/products/" + vm.SKU + ".jpg",
WeightInGrams = vm.WeightInGrams,
Size = vm.Size,
Quantity = vm.Quantity,
RetailPrice = vm.RetailPrice,
DiscountedPrice = vm.DiscountedPrice,
ShortDescription = vm.ShortDescription,
FullDescription = vm.FullDescription,
PublicationDate = (DateTime?)DateTime.Now,
LastUpdated = (DateTime?)DateTime.Now,
IsArchived = false
};
_context.Products.Add(product);
_context.SaveChanges();
return RedirectToAction(nameof(ManageProduct));
}
问题是,当我想修改产品时,我想用默认情况下与产品关联的图像填充 IFormFile 输入,但保留了通过上传新图像来更改它的可能性。我尝试了多种方法,以便在加载新页面时 ViewModel 包含一个 IFormFile,但都不起作用。我目前的代码(见下文)创建了 IFormFile 对象,其中包含属性方面所需的所有内容,但是在加载页面时,输入不会预先填充。
public IActionResult EditProduct(Guid id)
{
ViewBag.Id = id;
var toEdit = _context.Products.Find(id);
if (toEdit is null)
throw new ArgumentOutOfRangeException(nameof(id));
IFormFile? toEditImage = null;
string toEditFullImagePath = _hostingEnvironment.WebRootPath + toEdit.ImagePath![1..];
if (System.IO.File.Exists(toEditFullImagePath))
{
using (FileStream fileStream = new FileStream(toEditFullImagePath, FileMode.Open, FileAccess.Read))
{
var fileName = Path.GetFileName(toEditFullImagePath);
var provider = new FileExtensionContentTypeProvider();
if (!provider.TryGetContentType(fileName, out var contentType))
{
contentType = "application/octet-stream"; // Utilisez un type MIME par défaut si l'extension n'est pas reconnue.
}
var headers = new HeaderDictionary
{
["Content-Disposition"] = new StringValues("form-data; name=\"Image\"; filename=\"" + fileName + "\""),
["Content-Type"] = new StringValues(contentType)
};
toEditImage = new FormFile(fileStream, 0, fileStream.Length, fileName, fileName)
{
Headers = headers
};
}
}
else
{
ModelState.AddModelError(string.Empty, "L'image du produit n'a pas été trouvée.");
}
var vm = new AdminEditProductVM
{
SKU = toEdit.SKU,
Name = toEdit.Name,
Brand = toEdit.Brand,
Model = toEdit.Model,
Image = toEditImage,
WeightInGrams = toEdit.WeightInGrams,
Size = toEdit.Size,
Quantity = toEdit.Quantity,
RetailPrice = toEdit.RetailPrice,
DiscountedPrice = toEdit.DiscountedPrice,
ShortDescription = toEdit.ShortDescription,
FullDescription = toEdit.FullDescription
};
return View(vm);
}
如果您需要 html 输入或 ViewModel 中的任何代码,请告诉我。先谢谢你!
答:
0赞
Rena
11/2/2023
#1
出于安全原因,您无法以编程方式在浏览器中设置默认选择的文件。这将是一个严重的安全漏洞。用户必须通过文件输入字段手动选择文件。
你可以设置一个隐藏的输入,当你不想改变产品图片时,你可以不选择一个文件再发布到后端来判断文件是否为空。如果文件输入不为 null,则可以执行类似 did 的操作来更新值。如果为 null,则只需调用数据库更新查询。ImagePath
CreateProduct
ImagePath
评论
0赞
RayViLOz
11/2/2023
感谢您的快速回答。我可能会这样做,以便您必须选中一个复选框以表示您要修改图像,并在选中该复选框时显示输入。
评论