Question : ASP.NET Literal loses Text Value on Postback

I have a web page that doesn't seem to preserve a literal control's Text property on postback. Here is the markup:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
<%@ Page Language="VB" AutoEventWireup="false" MasterPageFile="~/MyMaster.master" CodeFile="MyPage.aspx.vb" Inherits="MyPage" %>
<%@ MasterType VirtualPath="~/MyMaster.master" %>

<asp:Content ID="MasterContent" ContentPlaceHolderID="MasterContent" Runat="Server">
  <div style="padding: 3px;" >
      <button id="btnLinkMerchant" style="width:75px; border:solid 1px #66CCFF;" 
          onserverclick="btnLinkMerchant_Click" runat="server"
        >
          <img id="imgLinkMerchant" runat="server" src="~/images/merchantAdd.jpg" alt="" /><br />
          <asp:Literal ID="litLinkMerchant" runat="server" Text="Opt In" />
      </button>
  </div>
</asp:Content>


Here's the code behind:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
Partial Class MyPage
    Inherits System.Web.UI.Page

    Public Property MerchantID() As Integer
        Get
            Return CNull(ViewState("MerchantID"), -1)
        End Get
        Private Set(ByVal value As Integer)
            ViewState("MerchantID") = value
        End Set
    End Property

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not Page.IsPostBack Then
            Call DisplayInfo(1)  ' dummy value
        End If
    End Sub

    Private Sub DisplayInfo(ByVal nInfoID As Integer)
        Dim ws As New MyWebService

        Dim sXML As String = ws.GetInfo(nInfoID)
        Dim reader As New System.IO.StringReader(sXML)
        Dim ds As New DataSet
        ds.ReadXml(reader)

        ' Need to figure out if linked to merchant
        If ds.Tables(0).Rows.Count > 0 Then
            ' Determine Merchant
            MerchantID = ds.Tables(0).Rows(0).Item("MerchantID")

            ' Determine Opt In 
            Call DisplayOptInOut(ds.Tables(0).Rows(0).Item("OptInInd"))
        End If
    End Sub

    Private Sub DisplayOptInOut(ByVal bIsOptIn As Boolean)
        If bIsOptIn Then
            ' Show Opt Out
            Me.imgLinkMerchant.Src = "~/images/merchantRemove.jpg"
            Me.litLinkMerchant.Text = "Opt Out"
        Else
            ' Show Opt In
            Me.imgLinkMerchant.Src = "~/images/merchantAdd.jpg"
            Me.litLinkMerchant.Text = "Opt In"
        End If
    End Sub

    Public Sub btnLinkMerchant_Click(ByVal sender As Object, ByVal e As EventArgs)
        Call LinkUnlinkMerchant()
    End Sub

    Private Sub LinkUnlinkMerchant()
            ' Add / Remove Favorite
            Dim bLink As Boolean = (Me.litLinkMerchant.Text = "Opt In")     ' desired action

            Dim ws As New MyWebService
            If bLink Then
                ws.LinkToMerchant(MerchantID)
            Else
                ws.UnlinkFromMerchant(MerchantID)
            End If

            Call DisplayInfo(1)
    End Sub

End Class


When I run the page, the button initially shows Opt-In. If I click it, the page posts back and correctly displays Opt-Out. (The database values are being correctly updated by the web service methods.)

But if I now click on the Opt-Out button, it stays Opt-Out. If I step through the code, I found that the text for the literal says still says Opt-In during page_load even though the button event changed it's text to Opt-In. Since the literal's viewstate is enabled by default, shouldn't its text value be Opt-In on postback?

In stepping through this, I did notice that it seems like some routines are called twice. Since I'm toggling the literal's value I wonder if I'm flipping it twice and thus causing this error. But I don't see where that's happening yet.

Thanks in advance.

Answer : ASP.NET Literal loses Text Value on Postback

I used a viewstate property to track OptIn status instead of the literal conrol text and that did the trick.
Random Solutions  
 
programming4us programming4us