Accessing ViewState Object From Outside Of Its Page Class Using StateBag Object

Posted at : Apr/04/2008
4862 Views

Alkisah terdapat dua orang programmer dalam sebuah perusahaan konsultan IT yang ditugaskan untuk membuat sebuah aplikasi web yang ditujukan untuk keperluan client perusahaan tersebut. Kedua programmer tersebut memiliki skill programming yang berbeda, satu memiliki skill di VB.NET dan satu lagi memiliki skill di C#. Mereka bekerja dalam satu team development. Salah satu kebutuhan aplikasi web tersebut diantaranya ialah membuat sebuah halaman yang digunakan untuk input data-data customer baru yang akan di output kan kedalam sebuah file xml yang akan di konsumsi nantinya oleh sebuah aplikasi desktop sebagai parser tool file xml tersebut.

Kemudian terjadilah percakapan diantara mereka untuk mendiskusikan apa yang sebaiknya harus mereka lakukan untuk memenuhi kebutuhan aplikasi tersebut. Sebut saja kedua orang tersebut Andra dan Eross...Andra memiliki skill di VB.NET sedangkan Eross di C#.

Andra : ross...gimana caranya membuat halaman tersebut, cara apa yang paling efektif untuk memenuhi kebutuhan itu?

Eross : karena data customernya bisa lebih dari satu dalam satu kali simpan data, kita tampung dulu semua data customer itu sebelum disimpan.

Andra : ya tapi gimana caranya?

Eross : simpan aja data customer itu di object generic List.

Andra : lo kan tau aplikasi web itu sifatnya stateless, ga bisa maintain state antara client dan server...kita ga bisa pake public variable kayak di aplikasi desktop.

Eross : lha lo ini gimana sih...kan bisa tuh pake ViewState..

Andra : o iya yah...kenapa ga pake Session ross?

Eross : soalnya ini data customer hanya di tampung di collection pada satu halaman web saja dan ga di share di halaman web lainnya, jadi ga perlu pake session.

Andra : o jadi klo ViewState itu ga bisa di share ya di halaman lainnya? ic ic...klo gitu jadi nanti kita buat sebuah class sebagai entity customernya trus buat ObjectDataSource control untuk mapping entity customer yang datanya disimpan di ViewState...btw gimana caranya akses ViewState di sebuah halaman dari luar class halaman tersebut? bisa gitu??

Eross : itu sih gampang bro...memang ViewState yang digunakan di sebuah halaman  itu ga bisa diakses secara langsung dari luar class page tersebut, soale itu ViewState bawaan dari Page class yang sifatnya Protected...so kita bisa gunakan StateBag object.

Andra : tapi ane ga tau gimana caranya tu bro...saya cuma tau menggunakan ViewState nya aja..

Eross : ya ga masalah...gw aja yang ngerjain

Andra : tapi kan lo pake C# ane pake VB.NET...bisa gitu dicampur?

Eross : ah kau ini kemana aja sih bro...kan semenjak asp.net 2.0 kita udah bisa gunakan multiple language dalam sebuah web application...caranya serahin aja ke gw...tapi mereka kan minta outputnya ke file xml tuh, gimana ya caranya yang paling mudah buat file xml programmatically gitu? ane bingung klo pake XmlTextWriter, XPathDocument atau .net xml API lainnya...

Andra : hah...kau ini juga kemana aja coi...kan di VB 9.0 kita bisa pake XML Literal...cara yang paling mudah untuk buat file xml programmatically...klo ini serahin aja ke gw :)

Eross : sip dah klo gt...yo kita mulai kerja...

Akhirnya si Eross membuat code untuk entity customer dan class yang digunakan untuk akses ViewState dari luar page class dengan menggunakan StateObject...bila dalam sebuah web project menggunakan code VB.NET dan C# secara bersamaan maka harus dibuat terlebih dahulu setting yang mendefinisikan hal itu di file web.config. Caranya yaitu :

1. Buat folder baru dibawah folder App_Code misal CSCode dan VBCode

2. Tambahkan elemen berikut di file web.config (diantara elemen <system.web> )

<codeSubDirectories>
    <add directoryName="CSCode"/>
    <add directoryName="VBCode"/>
</codeSubDirectories>

berikut code untuk class customer yang disimpan di folder App_code/CSCode...

[Serializable]
public class Customer
{
    public Customer()
    {
    }

    public string IDCustomer
    {get;set;}

    public string Name
    {get;set;}

    public string Phone
    { get; set; }

    public string Address
    { get; set; }
}

berikut kode penggunaan StateBag untuk akses ViewState (disimpan di folder App_Code/CSCode) :

public class StateBagObject
{
    public StateBagObject()
    {
    }

    public static string StateBagKey;

    private static StateBag mStateBag;
    public static StateBag GetViewState
    {
        get { return mStateBag; }
        set { mStateBag = value; }
    }

    private static List<Customer> GetTempCustomers()
    {
        var listTemp = (List<Customer>)mStateBag[StateBagKey];
        return listTemp;
    }

    public static List<Customer> GetCustomerByID(string ID)
    {
        List<Customer> listTemp = GetTempCustomers();
        if (listTemp != null)
        {
            return listTemp.FindAll(
                (Customer customer) => customer.IDCustomer.Equals(ID));
        }
        else
        {
            return listTemp;
        }
    }
}

Design control pada page seperti pada gambar dibawah ini :

Didalam page tersebut terdapat control DetailsView yang digunakan untuk menampilkan detail customer yang dipilih lewat listbox agar dapat di edit. DetailsView tersebut menggunakan ObjectDataSource (ODS) control sebagai sumber datanya yang diambil dari class StateBagObject, berikut kode html ODS nya :

<asp:ObjectDataSource ID="ObjectDataSource1" 
runat="server" SelectMethod="GetCustomerByID"
    TypeName="StateBagObject">
    <SelectParameters>
        <asp:ControlParameter 
        ControlID="lbAvailableCustomer" Name="ID" 
        PropertyName="SelectedValue"
            Type="String" />
    </SelectParameters>
</asp:ObjectDataSource>

Akhirnya tugas si Eross selesai...sekarang tinggal tugasnya Andra untuk membuat code yang dibutuhkan oleh page tersebut agar dapat menyimpan data di dalam generic list customer yang disimpan di ODS dan meng-outputkannya ke file xml dengan menggunakan VB 9.0...mari kita lihat code si Andra.

Pertama dia buat prosedur untuk cek keberadaan list customer di viewstate pada page di atas :

Private Sub SetCustomerViewState()
    If ViewState("customers") Is Nothing Then
        Dim ListOfCustomers As New List(Of Customer)
        ViewState("customers") = ListOfCustomers
    End If
End Sub

kemudian dia buat sebuah fungsi untuk mengambil list customer yang telah disimpan di viewstate :

Private Function GetCustomerViewState() As List(Of Customer)
    '//cast viewstate ke list customer
    Return DirectCast(ViewState("customers"), List(Of Customer))
End Function

sambil dengerin lagu Surrender nya Andra & The Backbone si Andra (loh kok jeruk minum jeruk :P ) membuat sebuah fungsi untuk mencari list customer berdasarkan IDCustomer :

Private Function GetCustomerByID(ByVal ID As String) As Customer
    Dim listTemp = GetCustomerViewState()
    '//cari indeks list customer sesuai 
    '//kriteria IDCustomer yang dicari
    Dim index = listTemp.FindIndex( _
    Function(cust As Customer) cust.IDCustomer = ID)
    Return listTemp(index)
End Function

selanjutnya object ViewState di akses lewat object StateBag Object, disinilah intinya...

Protected Sub ObjectDataSource1_Selecting() _
Handles ObjectDataSource1.Selecting
    '//get viewstate dari page
    StateBagObject.GetViewState = Me.ViewState
    '//get ViewState("customers")
    StateBagObject.StateBagKey = "customers"
End Sub

sambil minum kopi panas merk xxx ia meneruskan kodenya untuk menambahkan customer baru ke list :

Protected Sub btnAddCustomer_Click() _
Handles btnAddCustomer.Click
    '//cek keberadaan viewstate
    SetCustomerViewState()

    '//get customers
    Dim customers = GetCustomerViewState()

    '//add new customer
    Dim newCust As New Customer With {.IDCustomer = _
    txtID.Text, _
    .Name = txtName.Text, .Phone = txtPhone.Text, _
    .Address = txtAddress.Text}

    customers.Add(newCust)

    '//update viewstate
    ViewState("customers") = customers

    '//list semua customer ke listbox
    lbAvailableCustomer.DataSource = customers
    lbAvailableCustomer.DataTextField = "IDCustomer"
    lbAvailableCustomer.DataValueField = "IDCustomer"
    lbAvailableCustomer.DataBind()
End Sub

untuk mengambil value yang ada di dalam kontrol DetailsView ia mengetikkan jari-jemarinya pada keyboard untuk membuat fungsi dibawah ini :

Private Function GetIDLabel() As Label
    Return DirectCast( _
    DetailsView1.FindControl("lblIdDetails"), Label)
End Function

Private Function GetNameTextBox() As TextBox
    Return DirectCast( _
    DetailsView1.FindControl("txtNameDetails"), TextBox)
End Function

Private Function GetPhoneTextBox() As TextBox
    Return DirectCast( _
    DetailsView1.FindControl("txtPhoneDetails"), TextBox)
End Function

Private Function GetAddressTextBox() As TextBox
    Return DirectCast( _
    DetailsView1.FindControl("txtAddressDetails"), TextBox)
End Function

sambil makan keripik kentang ia melanjutkannya membuat kode untuk update customer property yang di binding ke DetailsView

Protected Sub btnUpdate_Click(ByVal sender As Object, _
                              ByVal e As System.EventArgs)
    Dim listCustToUpdate = Me.GetCustomerByID(GetIDLabel.Text)
    With listCustToUpdate
        .Name = GetNameTextBox.Text
        .Phone = GetPhoneTextBox.Text
        .Address = GetAddressTextBox.Text
    End With
End Sub

dengan mata yang melirik ke yahoo messanger si Andra ini membuat kode untuk meng outputkan semua data customer yang terdapat di dalam list ke file xml dengan menggunakan XML Literal (ini nih yang saya suka...loh kok "saya" :P ..., maksudnya yang si Andra suka...:)  meskipun contohnya simple :P )

Protected Sub btnSaveToXML_Click() Handles btnSaveToXML.Click
        Dim custXML = <Customers>
                          <%= From customer In Me.GetCustomerViewState _
                              Select <Customer ID=<%= customer.IDCustomer %>>
                                         <Name><%= customer.Name %></Name>
                                         <Phone><%= customer.Phone %></Phone>
                                         <Address><%= customer.Address %></Address>
                                     </Customer> %>
                      </Customers>

        custXML.Save("..\..\custXML.xml")
        System.Diagnostics.Process.Start("..\..\custXML.xml")
    End Sub

selesailah sudah tugas si Andra dan si Eross meskipun mereka merupakan "superman" dengan salary yang pas-pasan tapi dia tetap melaksanakan tugasnya dengan professional :) ...berikut web previewnya :

kemudian terjadi percakapan lagi diantara mereka

Eross : wah ternyata vb ma c# bisa hidup dengan damai ya dra? keduanya saling melengkapi...

Andra : yup...kita jangan jadi fanatisme sempit dalam memilih itu barang, yang penting dapet duitnya, ha ha ha....

Eross : eh gimana klo kita posting aja ni artikel ke blog? biar ga ada "Language Of War" again :)

Andra : Ok...sip lah

Lalu si eross buka Windows Live Writer nya dan mulai nulis artikelnya itu secara offline dulu, dan akhirnya artikel itu di posting juga...


ABOUT ME

Rully Yulian MF
Rully Yulian Muhammad Firmansyah | Co-Founder & IT Trainer at Native Enterprise | Microsoft Azure Data Scientist | IBM RAG & Agentic AI | IBM Data Science & Data Analyst | Python Certified (PCEP, PCAP) | MOS, MTA, Xamarin Certified, ex MCT | ex MVP

CERTIFICATIONS

Microsoft Certified Associate
IBM RAG and Agentic AI Professional
IBM Data Science Professional IBM Data Analyst Professional
PCAP Associate Python Programmer Certified PCEP Entry Level Python Programmer Certified
Xamarin Certified
MOS 2007
MCPD MCTS
MCAD.NET

NATIVE ENTERPRISE

Native Enterprise - IT Training

FOLLOW ME

Youtube  X Twitter Facebook  Instagram  LinkedIn

RSS


NATIVE ENTERPRISE NEWS

© Copyright 2006 - 2026   Rully Yulian MF   All rights reserved.