2017-10-21 39 views
0

我從部分共享視圖中加載產品圖像,我試圖使用前一個問題中建議的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類型屬性在實體類的問題

+0

首先,您希望將文件存儲在磁盤和數據庫中?對於數據庫,您應該在您的實體中使用字節數組作爲屬性類型。應該在你的視圖模型中使用IFormFile。 – Shyju

+0

嗨@Shyju我只想將文件的路徑存儲在數據庫中,然後將文件存儲在磁盤上。抱歉應該更清楚。 – rogue39nin

+0

@Shyju我重新調整了編輯的內容,所以我在這個問題上讓新人更清楚。 – rogue39nin

回答

2

。根據評論,您想要將圖像存儲在磁盤中,並將表格中的圖像路徑存儲在表格中。所以只需從實體類定義中刪除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"); 

} 
+0

因此,這意味着我需要爲我的上傳創建一個類,然後只是沒有作出,但謝謝 – rogue39nin

+0

是的。將UI層關注與數據訪問層分開總是很好的做法。第一步不要在剃刀視圖中使用數據訪問層實體類。創建特定於視圖的視圖模型並使用它。 – Shyju

+0

如果記錄不存在,我將如何獲得產品ID尚未使用我的大部分代碼的腳手架,因此如果我是愚蠢的,請原諒我 – rogue39nin