之前上傳圖片的做法都是上傳到服務器上的文件夾中,再將url保存到數據庫。其實在MVC中將圖片上傳到數據庫很便捷的事情,而且不用去存url了。而且這種方式支持ie6(ie6不支持jquery自動提交form,認為其不安全,這里form是主動點擊提交的,所以就沒有這個問題,而uploadify自動提交是flash的方式)。
一、建立模型
場景是假設我們需要給一個Product編輯一張圖片。在模型中,先定義好兩個屬性,ImageData和ImageType
public class Product { [HiddenInput(DisplayValue=false)] public int ProductID { get; set; } [Required(ErrorMessage = "Please enter a product name")] public string Name { get; set; } [Required(ErrorMessage = "Please enter a description")] [DataType(DataType.MultilineText)]// 在前台會渲染成Textarea public string Description { get; set; } [Required] [Range(0.01, double.MaxValue, ErrorMessage = "Please enter a positive price")] public decimal Price { get; set; } [Required(ErrorMessage = "Please specify a category")] public string Category { get; set; } public byte[] ImageData { get; set; } [HiddenInput(DisplayValue = false)]//會讓改屬性在編輯的時候不顯示出來。 public string ImageType{ get; set; } }
二、存取方法
那在我們的控制器中,這樣定義Edit方法。MVC強大的模型綁定機制會自動的將前台form中的數據根據name轉換成我們需要的C#對象。當然后台代碼這里只是簡單的實現,文件大小和類型的判斷先略過。
[HttpPost] //保存 public ActionResult Edit(Product product, HttpPostedFileBase image) { if (ModelState.IsValid) { if (image != null) { product.ImageType = image.ContentType;//獲取圖片類型 product.ImageData = new byte[image.ContentLength];//新建一個長度等於圖片大小的二進制地址 image.InputStream.Read(product.ImageData, 0, image.ContentLength);//將image讀取到ImageData中 } // save the product repository.UpdateProduct(product);//更新一下 保存模型。 // add a message to the viewbag TempData["message"] = string.Format("{0} has been saved", product.Name); // return the user to the list return RedirectToAction("Index"); } else { // there is something wrong with the data values return View(product); } }
HttpPostedFileBase.inputStream 獲取一個Stream 對象,該對象指向一個上載文件,以准備讀取該文件的內容。

然后通過ID,將二進制轉化為圖片。
public FileContentResult GetImage(int productId) { Product prod = repository.Products.FirstOrDefault(p => p.ProductID == productId); if (prod != null) { return File(prod.ImageData, prod.ImageMimeType);//File方法直接將二進制轉化為指定類型了。 } else { return null; } }
FileContentResult 最適合將二進制數據轉換成文件,同類型還有FileStreamResult,FilePathResult,這三個都是繼承與FileResult。
更詳細的解釋大家可以參考Artech大神的博客 :了解ASP.Net MVC幾種ActionResult的本質
三、前台代碼
@using (Html.BeginForm("Edit", "Admin", FormMethod.Post, new { enctype = "multipart/form-data" })) { @Html.EditorForModel() <div class="editor-label">Image</div> <div class="editor-field"><div>Upload new image: <input type="file" name="Image" /></div> </div> <input type="submit" value="Save" /> @Html.ActionLink("Cancel and return to List", "Index") }
@Html.EditorForModel() 會根據我們的模型自動渲染出編輯界面,比如是bool型,就會生成checkbox,而不用一條一條去寫。不是太復雜的模型可以用這種較為快捷的方式
自動渲染的效果如下(勿噴,未處理樣式)
那再獲取圖片的時候,就可以通過調用GetImage方法來獲取。 和獲取驗證碼的方式一樣。 這種方式比之前上傳寫一堆腳本要好很多。
<div class="item"> @if (Model.ImageData != null) { <div style="float:left;margin-right:20px"> <img width="75" height="75" src="@Url.Action("GetImage", "Product", new { Model.ProductID })" /> </div> } ....... <h4>@Model.Price.ToString("c")</h4> </div>
希望這次分享對你有幫助~
參考書籍:Pro Asp.Net MVC3 Framwork