2011-10-18 212 views
1

我試圖將舊的ASP.NET應用程序轉換爲MVC(我剛剛學習MVC)。我需要在GridView中顯示圖像。圖像本身作爲數據類型圖像存儲在SQL Server表中。以前使用的代碼如下所示。有人可以建議使用MVC的方法嗎?我正在考慮創建一個可以嵌入標準視圖的部分頁面,但不確定這是否是正確的設計。從數據庫中讀取圖像並在視圖中顯示

謝謝!

` string sqlText = "SELECT * FROM Images WHERE img_pk = " + id; 
     SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString); 

     SqlCommand command = new SqlCommand(sqlText, connection); 
     connection.Open(); 
     SqlDataReader dr = command.ExecuteReader(); 
     if (dr.Read()) 
     { 
      //Response.Write("test"); 
      Response.BinaryWrite((byte[])dr["img_data"]); 
     } 
     connection.Close(); 
    } 

那麼就可以使用此圖像標記被引用:

<asp:Image Height="73" Width="80" ID="Image1" ImageAlign="Middle" ImageUrl='<%#"viewimage.aspx?id=" + Eval("ImageId") %>' runat="server"/></a></td> 
+0

代碼是動作方法,Image控件是圖片標籤,ImageUrl是圖片標籤的動作url。有點。 – bzlm

回答

7

的第一件事就是約在GridView的ASP.NET MVC應用程序忘記。服務器端控件,回發,視圖狀態,事件......所有這些都是不再存在的概念。

在ASP.NET MVC中,您可以使用模型,控制器和視圖。

所以,你可以寫一個控制器動作將從數據庫中獲取的圖像,併爲它服務:

public class ImagesController: Controller 
{ 
    public ActionResult Index(int id) 
    { 
     string sqlText = "SELECT img_data FROM Images WHERE img_pk = @id"; 
     using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString)) 
     using (var command = conn.CreateCommand()) 
     { 
      conn.Open(); 
      command.CommandText = sqlText; 
      command.Parameters.AddWithValue("@id", id); 
      using (var reader = command.ExecuteReader()) 
      { 
       if (!reader.Read()) 
       { 
        return HttpNotFound(); 
       } 

       var data = GetBytes(reader, reader.GetOrdinal("img_data")); 
       return File(data, "image/jpg"); 
      } 
     } 
    } 

    private byte[] GetBytes(IDataReader reader, int columnIndex) 
    { 
     const int CHUNK_SIZE = 2 * 1024; 
     byte[] buffer = new byte[CHUNK_SIZE]; 
     long bytesRead; 
     long fieldOffset = 0; 
     using (var stream = new MemoryStream()) 
     { 
      while ((bytesRead = reader.GetBytes(columnIndex, fieldOffset, buffer, 0, buffer.Length)) > 0) 
      { 
       byte[] actualRead = new byte[bytesRead]; 
       Buffer.BlockCopy(buffer, 0, actualRead, 0, (int)bytesRead); 
       stream.Write(actualRead, 0, actualRead.Length); 
       fieldOffset += bytesRead; 
      } 
      return stream.ToArray(); 
     } 
    } 
} 

,然後在你看來簡單:

<img src="@Url.Action("Index", "Images", new { id = "123" })" alt="" /> 

現在當然這一切的控制器行動是很好,花花公子,但你應該真正抽象所有數據訪問到存儲庫:

public interface IImagesRepository 
{ 
    byte[] GetImageData(int id); 
} 

然後實現您所使用的數據提供這個方法:

public class ImagesRepositorySql: IImagesRepository 
{ 
    public byte[] GetImageData(int id) 
    { 
     // you already know what to do here. 
     throw new NotImplementedException(); 
    } 
} 

最後你將你的控制器成爲數據庫無關。在應用程序層,現在弱它們之間的耦合,這將允許重複使用和單元測試他們在隔離:

public class ImagesController: Controller 
{ 
    private readonly IImagesRepository _repository; 
    public ImagesController(IImagesRepository repository) 
    { 
     _repository = repository; 
    } 

    public ActionResult Index(int id) 
    { 
     var data = _repository.GetImageData(id); 
     return File(data, "image/jpg"); 
    } 
} 

和最後一部分是配置你喜歡的DI框架注入庫的正確實施進入控制器。

+0

+1教學IoC和Repository模式回答無辜圖像顯示問題:D – rouen

+0

感謝您的回覆Darin!我插入你的代碼,它沒有太多修改。我現在需要更好地理解它。我不喜歡僅僅使用代碼示例而不知道它是如何工作的。 – Marcusg

相關問題