2011-04-19 85 views
2

我想上傳幾個數據庫圖像到SQL Server 2008R2上。我在C#中使用ASP.NET MVC 3。發生什麼事是我得到的圖像顯示,但問題是,第二個圖像顯示爲兩次。所以它是重複的。我不確定爲什麼沒有顯示第一張圖片。無法上傳多個數據庫圖像與asp.net mvc

我SubProductCategory4表有以下幾列(爲簡單起見)...

列名稱:圖像1和圖像2具有數據類型VARBINARY(MAX),另一列名稱:ImageMimeType有數據類型爲varchar(50)。

我的控制器,具有針對創建方法如下代碼...

[HttpPost] 
    public ActionResult Create([Bind(Exclude = "SubProductCategoryFourID")] SubProductCategory4 Createsubcat4, IEnumerable<HttpPostedFileBase> files, FormCollection collection) 
    { 
     if (ModelState.IsValid) 
     { 
      foreach (string inputTagName in Request.Files) 
      { 

    if (Request.Files.Count > 0) // tried Files.Count > 1 did 
              // not solve the problem 
        { 
         Createsubcat4.Image1 = (new FileHandler()).uploadedFileToByteArray((HttpPostedFileBase)Request.Files[inputTagName]); 
         Createsubcat4.Image2 = (new FileHandler()).uploadedFileToByteArray((HttpPostedFileBase)Request.Files[inputTagName]); 
         // var fileName = Path.GetFileName(inputTagName); 
         //var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName); 
        } 
        // moved db.AddToSubProductCategory4(Createsubcat4); 
        // here but did not solve the problem 
      } 
      db.AddToSubProductCategory4(Createsubcat4); 
      db.SaveChanges(); 
      return RedirectToAction("/"); 
     } 


    //someother code 

     return View(Createsubcat4); 
    } 

的getImage方法...

public FileResult GetImage(int id) 
    { 
     const string alternativePicturePath = @"/Content/question_mark.jpg"; 
     MemoryStream stream; 
     MemoryStream streaml; 

     SubProductCategory4 z = db.SubProductCategory4.Where(k => k.SubProductCategoryFourID == id).FirstOrDefault(); 

     if ((z != null && z.Image1 != null) && (z != null && z.Image2 != null)) 
     { 

       stream = new MemoryStream(z.Image1); 
       streaml = new MemoryStream(z.Image2); 
     } 

     else 
     { 
       var path = Server.MapPath(alternativePicturePath); 

      foreach (byte item in Request.Files) 
       { 
       HttpPostedFileBase file = Request.Files[item]; 
       if (file.ContentLength == 0) 
       { 
        continue; 
       } 
      } 

      stream = new MemoryStream(); 
      var imagex = new System.Drawing.Bitmap(path); 
      imagex.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg); 
      stream.Seek(0, SeekOrigin.Begin); 

      /* streaml = new MemoryStream(); 
      var imagey = new System.Drawing.Bitmap(path); 
      imagey.Save(streaml, System.Drawing.Imaging.ImageFormat.Jpeg); 
      streaml.Seek(0, SeekOrigin.Begin);*/ 
     } 

     return new FileStreamResult(stream,"image/jpg"); 

    } 

FileHandler.cs

public class FileHandler 
{ 
    public byte[] uploadedFileToByteArray(HttpPostedFileBase file) 
    { 
     int nFileLen = file.ContentLength; 
     byte[] result = new byte[nFileLen]; 

     file.InputStream.Read(result, 0, nFileLen); 

     return result; 
    } 

} 

create.cshtml .. 。

 @using (Html.BeginForm("Create", "ProductCategoryL4", "GetImage", 
    FormMethod.Post, new { enctype = "multipart/form-data" }))  
     //some code then... 
    <div class="editor-field"> 
    @Html.EditorFor(model => model.Image1) 
    <input type="file" id="fileUpload1" name="fileUpload1" size="23"/> 
    @Html.ValidationMessageFor(model => model.Image1) 
    </div> 

    <div class="editor-field"> 
    @Html.EditorFor(model => model.Image2) 
    <input type="file" id="fileUpload2" name="fileUpload2" size="23"/> 
    @Html.ValidationMessageFor(model => model.Image2) 
    </div> 

index.cshtml ...

<img src="@Url.Action("GetImage", "ProductCategoryL4", new { id = 
item.SubProductCategoryFourID })" alt="" height="100" width="100" /> 
</td> 
    <td> 
    <img src="@Url.Action("GetImage", "ProductCategoryL4", new { id = 
    item.SubProductCategoryFourID })" alt="" height="100" width="100" /> 
    </td> 

我使用VS2010使用,ASP.NET MVC3在C#與SQL Server 2008R2。提前致謝,但請只回答如果你知道答案。如果有更好的方法,請讓我知道。

回答

4

列出的代碼循環遍歷文件,並且對於每個文件,將Image1Image2都設置爲相同的事物。當您上傳2個文件時,它們都顯示爲圖像2,因爲這是應用於這兩個字段的最後一個圖像。

嘗試用更像這樣的東西代替循環,如果有足夠的圖像,則一次設置一個字段。

FileHandler fh = new FileHandler(); 

if (Request.Files.Count > 0) 
{ 
    Createsubcat4.Image1 = fh.uploadedFileToByteArray(Request.Files[0]); 
} 

if (Request.Files.Count > 1) 
{ 
    Createsubcat4.Image2 = fh.uploadedFileToByteArray(Request.Files[1]); 
} 

db.AddToSubProductCategory4(Createsubcat4); 

如果需要打開這個爲允許在未來更多的圖像,你要替換圖像的集合的Image1Image2領域,並再次使用您的循環,在添加的每個圖像上傳的文件集合。事情是這樣的:

FileHandler fh = new FileHandler(); 

foreach (HttpPostedFileBase uploadedImage in Request.Files) 
{ 
    Createsubcat4.Images.Add(fh.uploadedFileToByteArray(uploadedImage)); 
} 

db.AddToSubProductCategory4(Createsubcat4); 
db.SaveChanges(); 

編輯:

現在你正確保存圖像,你需要看看你GetImage行動第二次看。您會注意到,您正確地將兩個文件加載到內存中,但是當您指定您的操作結果時(return new FileStreamResult(stream,"image/jpg");),您只會返回第一個流。您需要一種方法在請求時返回第二個流。有幾種方法可以解決這個問題,添加另一個輸入參數來指定要加載哪個圖像或創建第二個操作,只返回第二個操作。

要創建兩個動作設置,您的代碼會是這個樣子:

public ActionResult GetImage1(int id) 
{ 
    const string alternativePicturePath = @"/Content/question_mark.jpg"; 
    MemoryStream stream; 

    SubProductCategory4 z = db.SubProductCategory4.Where(k => k.SubProductCategoryFourID == id).FirstOrDefault(); 

    if (z != null && z.Image1 != null) 
    { 
     stream = new MemoryStream(z.Image1); 
    } 
    else 
    { 
     var path = Server.MapPath(alternativePicturePath); 

     stream = new MemoryStream(); 
     var imagex = new System.Drawing.Bitmap(path); 
     imagex.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg); 
     stream.Seek(0, SeekOrigin.Begin); 
    } 

    return new FileStreamResult(stream,"image/jpg"); 
} 

public ActionResult GetImage2(int id) 
{ 
    const string alternativePicturePath = @"/Content/question_mark.jpg"; 
    MemoryStream stream; 

    SubProductCategory4 z = db.SubProductCategory4.Where(k => k.SubProductCategoryFourID == id).FirstOrDefault(); 

    if (z != null && z.Image2 != null) // the difference is here 
    { 
     stream = new MemoryStream(z.Image2); // the difference is also here 
    } 
    else 
    { 
     var path = Server.MapPath(alternativePicturePath); 

     stream = new MemoryStream(); 
     var imagex = new System.Drawing.Bitmap(path); 
     imagex.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg); 
     stream.Seek(0, SeekOrigin.Begin); 
    } 

    return new FileStreamResult(stream,"image/jpg"); 
} 

這些功能幾乎是相同的,並可以很容易地取得1這需要一個參數來選擇要加載的圖像。

public ActionResult GetImage(int id, int? imageNum) 
{ 
    imageNum = imageNum ?? 0; 

    const string alternativePicturePath = @"/Content/question_mark.jpg"; 
    MemoryStream stream; 

    SubProductCategory4 z = db.SubProductCategory4.Where(k => k.SubProductCategoryFourID == id).FirstOrDefault(); 

    byte[] imageData = null; 

    if (z != null) 
    { 
     imageData = imageNum == 1 ? z.Image1 : imageNum == 2 ? z.Image2 : null; 
    } 

    if (imageData != null) 
    { 
     stream = new MemoryStream(imageData); 
    } 
    else 
    { 
     var path = Server.MapPath(alternativePicturePath); 

     stream = new MemoryStream(); 
     var imagex = new System.Drawing.Bitmap(path); 
     imagex.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg); 
     stream.Seek(0, SeekOrigin.Begin); 
    } 

    return new FileStreamResult(stream,"image/jpg"); 
} 

此功能會指定imageNum作爲查詢參數,如:

http://www.mydomain.com/controllerName/GetImage/{id}?imageNum={imageNum}

+0

@NickLarsen - 我恐怕也沒有解決問題。您提供的代碼,第一張圖像顯示爲兩次。所以它是重複的。 – DiscoDude 2011-04-27 15:05:24

+0

@DiscoDude:所以現在你正在保存圖片,你的'GetImage'動作需要更新。更新我的回覆以幫助您更多。 – 2011-04-27 15:21:58

+0

@DiscoDude:更新的響應 – 2011-04-27 15:34:36

0

我認爲你的問題可能出現在這個循環中。因爲你是通過文件的列表迭代

foreach (string inputTagName in Request.Files) 
{ 
    if (Request.Files.Count > 0) 
    { 
     Createsubcat4.Image1 = (new FileHandler()).uploadedFileToByteArray((HttpPostedFileBase)Request.Files[inputTagName]); 
     Createsubcat4.Image2 = (new FileHandler()).uploadedFileToByteArray((HttpPostedFileBase)Request.Files[inputTagName]); 
     // var fileName = Path.GetFileName(inputTagName); 
     //var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName); 
    } 
} 
db.AddToSubProductCategory4(Createsubcat4); 

Request.Files.Count > 0應該永遠是正確的。然而,真正的問題是,在這個循環中,您會使用每個文件覆蓋Createsubcat4的屬性,然後在使用最後一個文件設置屬性之後,將這些屬性發送到數據庫。

如果您試圖向數據庫中添加多個記錄(每個圖像一個記錄),則需要在循環中移動AddToSubProductCategory4。如果您試圖將兩個圖像添加到該記錄中,我建議按名稱分配每個圖像,並跳過foreach循環。

+0

我沒有在循環中移動AddToSubProductCategory4發佈這個問題之前,但恐怕也解決不了問題。我在代碼上添加了一些評論。同樣將Request.Files.Count> 0更改爲1,這也沒有解決問題。還有其他建議嗎? – DiscoDude 2011-04-27 14:13:36

+0

@NickLarsen - 你能告訴我爲什麼?用於公共ActionResult GetImage(int id,int?imageNum)方法。 – DiscoDude 2011-06-17 17:17:54

+0

@DiscoDude:它使它們爲空,以便在指定參數時有一些指示。否則每次都會默認爲0,當用戶指定imageNum爲0時,會留下不明確的情況。 – 2011-06-20 21:19:44