尝试使用asp.net core

时间:2017-10-21 18:20:04

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

我正在从部分共享视图中加载产品图像,我正在尝试使用上一个问题中建议的Ifrom文件。

所以在我的产品控制器中,我有以下方法

修改

我只想保存文件在数据库中的路径,然后将文件保存在磁盘上,这是实现此目的的正确方法。

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; }
}

我正在通过以下方式加载我的共享布局。

<div class="tab-pane" id="images">
        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]
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
    _context.ProductImages.Add(pi);
    _context.SaveChanges();

    }
    return RedirectToAction("Index", "Home");

}

现在我在另一个表单中加载表单的一件事可能是问题

1 个答案:

答案 0 :(得分:2)

您不应在实体类中使用IFormFile type属性。根据注释,您希望将图像存储在磁盘中,并将路径存储到表中的图像。所以只需从实体类定义中删除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的图像,创建此视图模型的对象,将ProductId设置为56并发送到GET操作中的视图。在视图中,我们将productId保存在隐藏的表单字段中,当我们需要保存新的ProductImages实体记录时,可以在HttpPost操作中稍后使用该字段。

public IActionResult UploadImage(int productId)
{
  var vm = new ProductImageVm { ProductId=productId};
  return View(vm);
}

和视图,它是我们的视图模型的强类型

@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>

现在,在您的HttpPost操作方法中,使用与参数相同的视图模型,读取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");

}