尝试使用asp.net核心上传文件
我从部分共享视图中加载产品图像,我试图使用前一个问题中建议的Ifrom文件。尝试使用asp.net核心上传文件
所以在我的产品控制器,我有以下方法
编辑
我只想保存文件的路径在数据库中,然后保存在磁盘上的文件是什么正确的方式来实现这一点。
public ActionResult FileUpload(ProductImages model)
{
if (model.Image != null)
{
var uploads = Path.Combine(hostingEnvironment.WebRootPath, "uploads");
var filePath = Path.Combine(uploads, GetUniqueName(model.Image.FileName));
model.Image.CopyTo(new FileStream(filePath, FileMode.Create));
}
// to do : Return something
return RedirectToAction("Index", "Home");
}
我的产品图片类
public class ProductImages
{
[Key]
public int ProductImageId { get; set; }
public int ProductID { get; set; }
public string ProductImageTitle { get; set; }
public string ProductImageUploadUrl { get; set; }
public string ProductImageRealPath { get; set; }
public string ServerIpAddress { get; set; }
public string ProductImageAltTag { get; set; }
public int DisplayOrder { get; set; }
public IFormFile Image { set; get; }
}
我的共享布局,我通过以下加载。
Product Images
@await Html.PartialAsync("_ProductPicture", Model)
</div>
这是我认为我做错了什么与我已经宣布了IFormFile
@model solitude.models.ProductImages
<div class="form-group">
<form asp-action="FileUpload" enctype="multipart/form-data">
<input asp-for="ImageCaption" />
<input asp-for="ImageDescription" />
<input asp-for="MyImage" />
<input type="submit" />
</form>
</div>
我收到以下错误
的方式为我的共享视图代码AggregateException:发生一个或多个错误。 (属性“ProductImages.Image”是一个接口类型(“IFormFile”)的,如果是 导航属性通过将其流延到映射的实体类型手动配置此 属性的关系,否则使用该忽略 属性。 '[NotMapped]' 属性或通过在 'OnModelCreating' 使用 'EntityTypeBuilder.Ignore') System.Threading.Tasks.Task.ThrowIfExceptional(布尔 includeTaskCanceledExceptions)
InvalidOperationException异常:属性“ProductImages.Image '是一个 接口类型('IFormFile')。如果它是一个手动导航属性 通过将其转换为映射的 实体类型来配置此属性的关系,否则使用'[NotMapped]' 属性或使用'OnModelCreating'中的'EntityTypeBuilder.Ignore'来忽略该属性。
编辑2
[HttpPost] 公共的ActionResult文件上传(ProductImageVm模型) { 如果(model.Image!= NULL){ 变种 上传= Path.Combine(hostingEnvironment.WebRootPath ,“上传”); var fileId = GetUniqueName(model.Image.FileName); VAR文件路径= Path.Combine(上载,FILEID); model.Image.CopyTo(新的FileStream(文件路径的FileMode。创建));
// to do : Save the record in ProductImage table
var pi = new ProductImages { ProductID = model.ProductId };
pi.ProductImageTitle = model.Title;
pi.ProductImageRealPath = fileId; //Storing the fileId
_context.ProductImages.Add(pi);
_context.SaveChanges();
}
return RedirectToAction("Index", "Home");
}
现在有一件事我加载另一个表单中的表单会这样你不应该使用IFormFile
类型属性在实体类的问题
。根据评论,您想要将图像存储在磁盘中,并将表格中的图像路径存储在表格中。所以只需从实体类定义中删除public IFormFile Image { set; get; }
属性。
您可以在您的视图模型中使用IFormFile
,该视图模型用于在视图和操作方法之间传输数据。因此,创建与视图
public class ProductImageVm
{
public int ProductId { set;get;}
public string Title { set;get;}
public IFormFile Image { set; get; }
//Add other properties AS NEEDED by your view
}
我们上传的图片进行产品56,创建这个视图模型的对象,产品ID设置为56,并发送至您的GET操作的视图需要的特性的视图模型。在视图中,我们将把productId保存在一个隐藏的表单域中,当我们需要保存一个新的ProductImages
实体记录时,可以稍后在HttpPost操作中使用它。
public IActionResult UploadImage(int productId)
{
var vm = new ProductImageVm { ProductId=productId};
return View(vm);
}
,并认为,这是强烈的HttpPost操作方法输入到我们的视图模型现在
@model ProductImageVm
<form asp-action="FileUpload" asp-controller="Products" method="post"
enctype="multipart/form-data">
<input asp-for="Title" />
<input asp-for="ProductId" type="hidden" />
<input asp-for="Image" />
<input type="submit" />
</form>
,您使用相同的视图模型的参数,请阅读Image
财产,并将其保存到磁盘并将路径存储在您的表中。您不需要存储完整路径。您可以存储相对路径。在下面的示例中,我保存ProductImages实体记录时将唯一文件Id(文件名)存储到ProductImageRealPath
属性值。
[HttpPost]
public ActionResult FileUpload(ProductImageVm model)
{
if (model.Image != null)
{
var uploads = Path.Combine(hostingEnvironment.WebRootPath, "uploads");
var fileId = GetUniqueName(model.Image.FileName);
var filePath = Path.Combine(uploads,fileId);
model.Image.CopyTo(new FileStream(filePath, FileMode.Create));
}
// to do : Save the record in ProductImage table
var pi=new ProductImages { ProductId = model.ProductId};
pi.ProductImageTitle = model.Title;
pi.ProductImageRealPath = fileId; //Storing the fileId
db.ProductImages.Add(pi);
db.SaveChanges();
return RedirectToAction("Index", "Home");
}
因此,这意味着我需要为我的上传创建一个类,然后只是没有作出,但谢谢 – rogue39nin
是的。将UI层关注与数据访问层分开总是很好的做法。第一步不要在剃刀视图中使用数据访问层实体类。创建特定于视图的视图模型并使用它。 – Shyju
如果记录不存在,我将如何获得产品ID尚未使用我的大部分代码的脚手架,因此如果我是愚蠢的,请原谅我 – rogue39nin
首先,您希望将文件存储在磁盘和数据库中?对于数据库,您应该在您的实体中使用字节数组作为属性类型。应该在你的视图模型中使用IFormFile。 – Shyju
嗨@Shyju我只想将文件的路径存储在数据库中,然后将文件存储在磁盘上。抱歉应该更清楚。 – rogue39nin
@Shyju我重新调整了编辑的内容,所以我在这个问题上让新人更清楚。 – rogue39nin