ASP.NET MVC Hands On Labs (Part2 – Membuat Model dan Controller)

Tutorial ini adalah sambungan dari Hands On Labs ASP.NET MVC Part1

Membuat Product Repository

Pada small application tidak menjadi masalah jika kita mengakses LINQ to SQL DataContex class langsung dari Controller, namun jika aplikasinya bertambah kompleks maka akan sulit untuk di maintain dan melakukan tes terhadap kode-kode tersebut, akan terjadi duplikasi banyak code pada aplikasi kita (berlawanan dengan prinsip MVC yaitu DRY = Don’t Repeat Yourself).
Teknik yang dapat digunakan untuk membuat aplikasi kita lebih mudah di maintain adalah dengan menggunakan “repository pattern” yaitu membuat repository class yang mengenkapsulasi query dan persistance logic sehingga aplikasi kita menjadi lebih clean.
1.  Tambahkan class baru kedalam folder “Model”, beri nama “ProductRepository.cs”. kemudian tulis kode berikut:

   1: namespace ComputerStore.Models {

   2:     public class ProductRepository {

   3:         StoreDataContext db = new StoreDataContext();

   4:  

   5:         //menampilkan semua product, digunakan pada View Index

   6:         public IQueryable<Product> ShowAllProduct() {

   7:             var query = from p in db.Products

   8:                         orderby p.Id

   9:                         select p;

  10:             return query;

  11:         }

  12:  

  13:         //menambah product baru, digunakan pada View Create

  14:         public void CreateProduct(Product productToCreate) {

  15:             db.Products.InsertOnSubmit(productToCreate);

  16:         }

  17:  

  18:         //mengambil product berdasarkan id tertentu

  19:         public Product ShowProduct(int id) {

  20:             Product prod = db.Products.Where(p => p.Id == id).Single<Product>();

  21:             return prod;

  22:         }

  23:  

  24:         //mengedit product

  25:         public void EditProduct(Product productToEdit) {

  26:             Product prod = db.Products.Where(p => p.Id == productToEdit.Id).Single<Product>();

  27:             prod.Name = productToEdit.Name;

  28:             prod.Price = productToEdit.Price;

  29:             prod.Qty = productToEdit.Qty;

  30:             prod.BuyDate = productToEdit.BuyDate;

  31:         }

  32:  

  33:         //menghapus product

  34:         public void DeleteProduct(int id) {

  35:             Product prod = db.Products.Where(p => p.Id == id).Single<Product>();

  36:             db.Products.DeleteOnSubmit(prod);

  37:         }

  38:  

  39:         public void Save() {

  40:             db.SubmitChanges();

  41:         }

  42:     }

  43: }

2.  StoreDataContext adalah class yang digenerate oleh tools LINQ to SQL Classes, yang berisi object model dari table Products. Untuk mngakses data maka kita menggunakan standar query expression dari LINQ. Query expression tersebut akan diterjemahkan oleh LINQ to SQL menjadi T-SQL sintaks untuk dieksekusi oleh database.

Membuat Controller

Sesudah membuat Model, kemudian langkah selanjutnya adalam membuat Controller. Pada aplikasi MVC, Controller Berisi Control-flow logic. Controller berinteraksi dengan Model dan View untuk mengontrol jalannya aplikasi. 
1.  Pada solution explorer klik kanan folder “Controller”, pilih “Add” – “Controller”, beri nama “Home Controller”, kemudian check pada pilihan “Add action method  for create, update, and details scenario” untuk menambahkan secara otomatis ActionMethod yang akan kita buat untuk menghandle proses CRUD (create, read, update, dan delete) .

2.  Kemudian tambahkan kode berikut pada Controller:

   1: namespace ComputerStore.Controllers

   2: {

   3:     public class HomeController : Controller

   4:     {

   5:         private ProductRepository productRepo = new ProductRepository();

   6:         //

   7:         // GET: /Home/

   8:  

   9:        public ActionResult Index() {

  10:             return View(productRepo.ShowAllProduct());

  11:        }

  12:  

  13:         public ActionResult About() {

  14:             return View();

  15:         }

  16:  

  17:  

  18:         //

  19:         // GET: /Home/Details/5

  20:  

  21:         public ActionResult Details(int id)

  22:         {

  23:             return View();

  24:         }

  25:  

  26:         //

  27:         // GET: /Home/Create

  28:  

  29:         public ActionResult Create()

  30:         {

  31:             return View();

  32:         } 

  33:  

  34:         //

  35:         // POST: /Home/Create

  36:  

  37:         [AcceptVerbs(HttpVerbs.Post)]

  38:         public ActionResult Create([Bind(Exclude="Id")] Product productToCeate)

  39:         {

  40:             if (ModelState.IsValid) {

  41:                 try {

  42:                     // TODO: Add insert logic here

  43:                     productRepo.CreateProduct(productToCeate);

  44:                     productRepo.Save();

  45:                     return RedirectToAction("Index");

  46:                 }

  47:                 catch {}

  48:             }

  49:             return View(productToCeate);

  50:         }

  51:  

  52:         //

  53:         // GET: /Home/Edit/5

  54:  

  55:         public ActionResult Edit(int id)

  56:         {

  57:             return View(productRepo.ShowProduct(id));

  58:         }

  59:  

  60:         //

  61:         // POST: /Home/Edit/5

  62:  

  63:         [AcceptVerbs(HttpVerbs.Post)]

  64:         public ActionResult Edit(Product productToEdit)

  65:         {

  66:             if (ModelState.IsValid) {

  67:                 try {

  68:                     // TODO: Add update logic here

  69:                     productRepo.EditProduct(productToEdit);

  70:                     productRepo.Save();

  71:                     return RedirectToAction("Index");

  72:                 }

  73:                 catch {}

  74:             }

  75:             return View(productToEdit);

  76:         }

  77:  

  78:         public ActionResult Delete(int id) {

  79:             Product prod = productRepo.ShowProduct(id);

  80:             return View(prod);

  81:         }

  82:  

  83:         [AcceptVerbs(HttpVerbs.Post)]

  84:         public ActionResult Delete(int id,string confirmButton) {

  85:             try {

  86:                 productRepo.DeleteProduct(id);

  87:                 productRepo.Save();

  88:             }

  89:             catch {}

  90:             return View("Deleted");

  91:         }

  92:  

  93:     }

  94: }

Kemuadian langkah selanjutnya adalah pembuatan “View” yang akan dijelaskan di bagian selanjutnya ..

ASP.NET MVC Hands On Labs (Part1)

Pada tutorial kali ini saya akan mengajak anda mencoba framework terbaru untuk mengembangkan aplikasi berbasis web menggunakan Model View Controller Pattern yaitu ASP.NET MVC. Tutorial ini berisi langkah-langkah praktis yang disertai studi kasus untuk membangun aplikasi sederhana (katalog product) menggunakan ASP.NET MVC. Selain menggunakan fitur-fitur yang ada di ASP.NET MVC, tutorial ini juga membahas sedikit integrasi ASP.NET MVC dengan salah satu javascript framework yang banyak digunakan yaitu JQuery.

Adapun beberapa software yang harus diinstal untuk menjalankan HOL ini adalah:

  • Visual Studio 2008 SP1
  • ASP.NET MVC 1.0
  • SQL Server Express 2005
  • JQuery 1.3
  • JQuery UI 1.7.1

Topik yang akan dibahas pada contoh ini:

  • Membuat Model (LINQ to SQL)
  • Membuat Class Repository
  • Membuat Controller 
  • Membuat View (Helper, Validation) 
  • Simple JQuery Integration

 

Membuat Database dan Data Model

Pertama kita akan membat database yang akan kita gunakan dalam aplikasi ini, untuk itu ikuti
langkah-langkah dibawah ini:  

1.  Buka VS 2008, kemudian buat project ASP.NET MVC, beri nama “ComputerStore”

image

2.  Kemudian pada Solution Explorer, klik kanan folder “App_Data”

image

3.  Kemudian pada database tambahkan table dengan nama “Products”, dan tambahkan field-field berikut pada table “Products”. 

image

4.  Pada field “Id” ubah property “Identity Specification” menjadi “Yes” untuk menambahkan auto increment pada field tersebut.

image

 

Membuat Data Model (LINQ to SQL)

Setelah kita selesai membuat database, sekarang saatnya melakukan mapping table yang sudah kita buat menjadi object model dengan menggunakan LINQ to SQL. Object model ini akan kita simpan di dalam folder “Model”. Pada aplikasi MVC model berisi semua application logic (bussiness logic, data access logic).
1.  Pada Solution Explorer, klik kanan folder “Model”, kemudian pilih “Add” – “New Item” – pilih
“LINQ to SQL Classes” untuk membuat object model (mapping) secara otomatis. Anda dapat juga menggunakan “SQL Metal” atau melakukan mapping table secara manual.

image 

2.  Beri nama “Store.dbml”. Kemudian drag table “Products” dari server explorer kedalam LINQ to SQL Diagram. Kemudian save.

image

Setelah data model selesai kita buat, maka langkah selanjutnya adalah mendesain Product Repository yang adakan dijelaskan pada blog selanjutnya

VB.NET Ebook Gratis dalam Bahasa Indonesia

VBNET_Migration_thumb_1338A82A

Satu bulan yang lalu saya dan teman saya Bapak Rully selesai menulis sebuah buku gratis dalam bahasa indonesia dengan judul “Migrasi Visual Basic 6 ke Visual Basic.NET”. Buku ini kami persembahkan ke komunitas INDC dan komunitas IT di Indonesia. Anda dapat mendownload buku ini secara gratis disini

Buku setebal 225 halaman ini membahas Fitur-fitur terbaru yang ada di VB9 dan menunjukan perbedaan VB6 dan VB.NET, cocok untuk anda developer VB6 yang ingin belajar VB.NET. adapun bab-bab yang dibahas pada buku ini adalah:

PENGANTAR ………………………………………………………………………………………………. 1
BAB 1 MIGRASI KE .NET FRAMEWORK ……………………………………………… 8
BAB 2 VISUAL STUDIO IDE …………………………………………………………………… 17
BAB 3 DASAR VB 2008 …………………………………………………………………………….. 29
BAB 4 WINDOWS FORM ………………………………………………………………………… 75
BAB 5 OBJECT ORIENTED PROGRAMMING …………………………………. 101
BAB 6 OBJEK ORIENTED PROGRAMMING BAGIAN 2 ………………… 123
BAB 7 COLLECTION …………………………………………………………………………….. 144
BAB 8 PENANGANAN KESALAHAN………………………………………………….. 151
BAB 9 FITUR BARU VB9……………………………………………………………………….. 165
BAB 10 VB 6.0 TO VB.NET MIGRATION TOOLS HELPER ……………. 196

Harapan saya semoga buku ini dapat bermanfaat bagi anda sekalian, selamat menikmati :)

MVP Award

OLYMPUS DIGITAL CAMERA          

Pada bulan July 2009 saya mendapatkan kado istimewa berupa award Microsoft MVP (Most Valuable Professional) untuk bidang keahlian Visual Basic (https://mvp.support.microsoft.com/profile/erick).

MVP adalah penghargaan yang diberikan oleh Microsoft kepada para profesional bidang teknologi informasi (TI) atas keahlian dan kontribusi mereka terhadap komunitas TI. Penghargaan MVP diberikan oleh Microsoft kepada individu yang tidak hanya memiliki keahlian pada satu atau beberapa produk Microsoft, tetapi juga memberikan kontribusi yang signifikan serta berperan aktif dalam komunitas, baik secara offline maupun online. 

Terima Kasih kepada Teman-teman di Microsoft Indonesia, Komunitas INDC (Indonesia Developer Community) dan MUGI (Microsoft User Group) yang telah banyak membantu saya sehingga saya dapat memperoleh penghargaan yang cukup bergengsi ini.

Acara Seminar Technology Update di UNY

8220_1122963313638_1213743176_30328591_7334977_n

Pada tanggal 10 Oktober 2009 akan diadakan Seminar Technology Update di Universitas Negri Yogyakarta (UNY). Pada seminar tersebut saya mewakili MUGI (Microsoft User Group Indonesia) Jogja akan menyampaikan materi Pengenalan Kominitas MUGI dan Windows 7 for Developer menggunakan Windows7 CodePack API.

LIstView dan Data Pager Control (bagian 2)

Posting ini adalah lanjutan dari posting sebelumnya di

Topik yang akan dibahas pada posting kali ini:

  • Sorting dengan ListView
  • Edit, Delete data dengan ListView
  • Insert data dengan ListView
  • Sekilas DataPager Control
  • Contoh menggunakan DataPager
  • Custom Paging

Source code untuk contoh-contoh aplikasi dapat anda download di

Sorting Dengan ListView

Anda juga dapat menambahkan sorting pada ListView control dengan cara merubah property ‘CommandName’ menjadi ‘Sort’ dan ‘CommandArgument’ berisi nama kolom untuk yg akan disorting.

Contoh sorting dengan ListView Control (ListSort.aspx)

   1: <form id="form1" runat="server">
   2: <div>
   3:   <asp:SqlDataSource ID="sdsKategori" runat="server"
   4:     ConnectionString="<%$ 
   5:     ConnectionStrings:MhsConnectionString %>"
   6:     SelectCommand="SELECT * FROM 
   7:       Kategori"></asp:SqlDataSource>
   8:    <asp:ListView ID="lvBerita" runat="server"
   9:      DataSourceID="sdsKategori">
  10:      <LayoutTemplate>
  11:       <table border="1px" style="border-collapse:collapse;">
  12:         <thead>
  13:         <tr>
  14:           <th><asp:LinkButton ID="lnkId" Text="ID"
  15:             CommandName="Sort" CommandArgument="id_kat"
  16:             runat="server" /></th>
  17:           <th><asp:LinkButton ID="lnkNama" Text="Nama 
  18:             Kategori" CommandName="Sort"
  19:             CommandArgument="nama_kat"
  20:             runat="server" /></th>
  21:         </tr>
  22:         </thead>
  23:         <tbody>
  24:           <asp:PlaceHolder ID="itemPlaceHolder"
  25:             runat="server" />
  26:         </tbody>
  27:       </table>
  28:      </LayoutTemplate>
  29:      <ItemTemplate>
  30:        <tr>
  31:          <td><%# Eval("id_kat") %></td>
  32:          <td><%# Eval("nama_kat") %></td>
  33:        </tr>
  34:      </ItemTemplate>
  35:    </asp:ListView>
  36: </div>
  37: </form>

image

Edit, Delete, Insert Data dengan ListView

ListView menggunakan tag-tag <EditItemTemplate>, <DeleteItemTemplate>, <InsertItemTemplate> untuk inser, edit, delete data. Didalam tag tersebut anda dapat membuat tampilan ketika tombol edit, insert, atau delete ditekan.

Contoh Edit dan Delete data menggunakan ListView (EditList.aspx)

   1: <form id="form1" runat="server">
   2: <div>
   3:   <asp:SqlDataSource ID="sdsKategori" runat="server"
   4:     ConnectionString="<%$ 
   5:     ConnectionStrings:MhsConnectionString %>"
   6:     SelectCommand="SELECT * FROM [Kategori]"
   7:     DeleteCommand="DELETE FROM [Kategori] 
   8:       WHERE [id_kat] = @id_kat"
   9:     UpdateCommand="UPDATE [Kategori] SET [nama_kat] = 
  10:       @nama_kat WHERE [id_kat] = @id_kat">
  11:     <DeleteParameters>
  12:       <asp:Parameter Name="id_kat" Type="Int32" />
  13:     </DeleteParameters>
  14:     <UpdateParameters>
  15:       <asp:Parameter Name="nama_kat" Type="String" />
  16:       <asp:Parameter Name="id_kat" Type="Int32" />
  17:     </UpdateParameters>
  18:   </asp:SqlDataSource>
  19:   <asp:ListView ID="lvKategori" runat="server"
  20:     DataKeyNames="id_kat" DataSourceID="sdsKategori">
  21:     <LayoutTemplate>
  22:      <asp:PlaceHolder ID="itemPlaceholder" runat="server" />
  23:     </LayoutTemplate>
  24:     <ItemTemplate>
  25:       <div style="border:solid 1px black;width:250px">
  26:         <h3><%# Eval("nama_kat") %></h3>
  27:         <p>Id: <%# Eval("id_kat") %></p><hr />
  28:         <asp:LinkButton id="lnkEdit" Text="{Edit}"
  29:           CommandName="Edit" Runat="server" />
  30:         <asp:LinkButton id="lnkDelete" Text="{Delete}"
  31:           CommandName="Delete" Runat="server"
  32:           OnClientClick="return confirm('Anda yakin 
  33:           mendelete data?')" />
  34:       </div>
  35:     </ItemTemplate>
  36:     <EditItemTemplate>
  37:       <div style="border:solid 1px black;width:250px">
  38:         Nama Kategori :<asp:TextBox ID="txtKat" Text='<%# 
  39:           Bind("nama_kat") %>' runat="server" />
  40:         <asp:RequiredFieldValidator ID="rfvKat"
  41:           runat="server" ControlToValidate="txtKat"
  42:           ErrorMessage="{required}" /><hr />
  43:         <asp:LinkButton id="lnkUpdate" Text="{Update}"
  44:           CommandName="Update" Runat="server" />
  45:         <asp:LinkButton id="lnkCancel" Text="{Cancel}"
  46:           CommandName="Cancel" Runat="server" />
  47:       </div>
  48:       </EditItemTemplate>
  49:   </asp:ListView>
  50: </div>
  51: </form>

image

image

Contoh insert data menggunakan ListView (InsertList.aspx)

   1: <form id="form1" runat="server">
   2: <div>
   3:   <asp:SqlDataSource ID="sdsKategori" runat="server"
   4:     ConnectionString="<%$ 
   5:     ConnectionStrings:MhsConnectionString %>"
   6:     InsertCommand="INSERT INTO [Kategori] ([nama_kat]) 
   7:       VALUES (@nama_kat)"
   8:     SelectCommand="SELECT * FROM [Kategori]">
   9:     <InsertParameters>
  10:       <asp:Parameter Name="nama_kat" Type="String" />
  11:     </InsertParameters>
  12:   </asp:SqlDataSource>
  13:   <asp:ListView ID="lvKategori" runat="server"
  14:     DataSourceID="sdsKategori"
  15:     InsertItemPosition="FirstItem">
  16:   <LayoutTemplate>
  17:     <asp:PlaceHolder ID="itemPlaceHolder" runat="server" />
  18:   </LayoutTemplate>
  19:   <ItemTemplate>
  20:    <div style="border:solid 1px black;width:250px">
  21:     <h3><%# Eval("nama_kat") %></h3>
  22:     <p>Id Kategori : <%# Eval("id_kat") %></p><hr />
  23:    </div>
  24:   </ItemTemplate>
  25:   <InsertItemTemplate>
  26:    <div style="border:solid 1px black;width:250px">
  27:      <h3>Tambah Kategori</h3>
  28:      Nama Kategori :<asp:TextBox ID="txtKat" Text='<%# 
  29:        Bind("nama_kat") %>' runat="server" /><hr />
  30:      <asp:LinkButton ID="lnkInsert" Text="{Insert}"
  31:        CommandName="Insert" runat="server" />
  32:    </div>
  33:   </InsertItemTemplate>
  34:   </asp:ListView>
  35: </div>
  36: </form>

image

DataPager Control

DataPager adalah pasangan dari ListView yang digunakan untuk paging halaman. DataPager dapat digunakan oleh semua control yang mengimplementasikan interface IPageableItemContainer. Di ASP.NET 3.5 baru ada satu control yang mengimplementasikan interface tersebut yaitu ListView ^_^

DataPager control mempunyai beberapa property yang penting yaitu:

  • PageSize: jumlah data yang akan ditampilkan.
  • PagedControlId: ambil atau set control pada halaman.
  • Fields: ambil fields yang ada pada DataPager.
  • StartRowIndex: ambil index dari item pertama yang ditampilkan.
  • MaximumRows: ambil maksimum row yang diambil dari data source.
  • TotalRowCount: ambil total number dari items yang ada pada data source.
  • NextPreviousPagerFields : untuk menampilkan link dalam bentuk next, previous, first dan last.
  • NumericPagerFileds: menampilkan link dalam bentuk numeric.
  • TemplatePagerField: membuat custom user interface pada paging.

Contoh menggunakan DataPager (ShowDataPager.aspx)

   1: <form id="form1" runat="server">
   2: <div>
   3:   <asp:SqlDataSource ID="sdsBerita" runat="server"
   4:     ConnectionString="<%$ 
   5:     ConnectionStrings:MhsConnectionString %>"
   6:     SelectCommand="SELECT * FROM 
   7:       [Berita]"></asp:SqlDataSource>
   8:     <asp:ListView ID="lvBerita" runat="server"
   9:       DataSourceID="sdsBerita">
  10:     <LayoutTemplate>
  11:     <table border="2">
  12:     <thead>
  13:       <th>Judul</th><th>Berita</th><th>Tanggal</th>
  14:     </thead>
  15:     <asp:PlaceHolder ID="itemPlaceHolder" runat="server" />
  16:     </table>
  17:     <asp:DataPager ID="dpBerita" PageSize="2"
  18:       runat="server">
  19:       <Fields>
  20:         <asp:NextPreviousPagerField
  21:           ShowFirstPageButton="true"
  22:           ShowPreviousPageButton="true"
  23:           ShowNextPageButton="false"
  24:           ShowLastPageButton="false" />
  25:         <asp:NumericPagerField />
  26:         <asp:NextPreviousPagerField
  27:           ShowFirstPageButton="false"
  28:           ShowPreviousPageButton="false"
  29:           ShowNextPageButton="true"
  30:           ShowLastPageButton="true" />
  31:       </Fields>
  32:     </asp:DataPager>
  33:     </LayoutTemplate>
  34:     <ItemTemplate>
  35:       <tr>
  36:         <td><%# Eval("judul_berita") %></td>
  37:         <td><%# Eval("detail_berita") %></td>
  38:         <td><%# Eval("tanggal") %></td>
  39:       </tr>
  40:     </ItemTemplate>
  41:   </asp:ListView>
  42: </div>
  43: </form>

image_thumb3

Membuat Custom Paging

Jika anda tidak puas dengan default paging yang disediakan, anda dapat menggunakan TemplatePagerField.

Contoh menggunakan DataPager TemplatePagerField (PagerTemplate.aspx)

   1: <form id="form1" runat="server">
   2: <div>
   3:   <asp:SqlDataSource ID="sdsBerita" runat="server"
   4:     ConnectionString="<%$ 
   5:     ConnectionStrings:MhsConnectionString %>"
   6:     SelectCommand="SELECT * FROM 
   7:       [Berita]"></asp:SqlDataSource>
   8:    <asp:ListView ID="lvBerita" runat="server"
   9:       DataSourceID="sdsBerita">
  10:     <LayoutTemplate>
  11:      <table border="1">
  12:      <thead>
  13:         <th>Judul</th><th>Berita</th><th>Tanggal</th>
  14:      </thead>
  15:      <asp:PlaceHolder ID="itemPlaceholder" runat="server" />
  16:      </table>
  17:      <asp:DataPager ID="dpBerita" runat="server"
  18:        PageSize="2">
  19:        <Fields>
  20:          <asp:TemplatePagerField
  21:            OnPagerCommand="dpBerita_OnPagerCommand">
  22:          <PagerTemplate>
  23:            <asp:LinkButton ID="lnkPrev" Text="{Prev}"
  24:              CommandName="Previous" runat="server" />
  25:            <asp:LinkButton ID="lnkNext" Text="{Next}"
  26:              CommandName="Next" runat="server" />
  27:          </PagerTemplate>
  28:          </asp:TemplatePagerField>
  29:        </Fields>
  30:      </asp:DataPager>
  31:     </LayoutTemplate>
  32:     <ItemTemplate>
  33:       <tr>
  34:         <td><%# Eval("judul_berita") %></td>
  35:         <td><%# Eval("detail_berita") %></td>
  36:         <td><%# Eval("tanggal") %></td>
  37:       </tr>
  38:     </ItemTemplate>
  39:    </asp:ListView>
  40: </div>
  41: </form>

Kemudian tambahkan kode berikut pada event ‘OnPagerCommand’ pada TemplateFields.

   1: protected void dpBerita_OnPagerCommand(object sender,
   2: DataPagerCommandEventArgs e) {
   3:     e.NewMaximumRows = e.Item.Pager.MaximumRows;
   4:     switch (e.CommandName) {
   5:     case "Previous":
   6:       if (e.Item.Pager.StartRowIndex > 0)
   7:         e.NewStartRowIndex = e.Item.Pager.StartRowIndex - 2;
   8:       break;
   9:     case "Next":
  10:         e.NewStartRowIndex = e.Item.Pager.StartRowIndex + 2;
  11:       break;
  12:     }
  13: }

image_thumb5

Dibandingkan dengan GridView, Kombinasi ListView dan DataPager menawarkan fleksibilitas yang lebih besar kepada programmer untuk memodifikasi tampilan dan program. Secara pribadi saya menyarankan penggunaan dua control baru ini daripada control lama seperti GridView, DataList, atau Repeater.

selesai ^_^