2011-10-18 19 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

まず最初に、ASP.NET MVCアプリケーションでのGridViewを忘れることです。サーバーサイドコントロール、ポストバック、ビューステート、イベント、...これらはすべて、もはや存在しない概念です。

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とリポジトリパターンを教えるために:D – rouen

+0

返信ありがとうDarin!私はあなたのコードを差し込んで、それは多くの変更なしで働いた。私は今それをより良く理解するためにそれをさらに理解する必要があります。どのように動作するのかわからずにコード例を使用するのは嫌です。 – Marcusg

関連する問題