:   +353 91 395 793
   :   +353 91 395 403
:   info@harvardinnovations.com
7 Joyce House, Tuam Road 
Galway City, Ireland
skype us

SelectedValue null when Dropdownlist EnableViewstate is false

The Problem

So you have embedded a Dropdownlist on your page, you have bound a lot of data to this Dropdownlist (such as a country list) and have an OnSelectedIndexChanged event associated with it. It works perfectly until you set enableviewstate="false" then your event doesn't get fired.  You desperately want to disable the ViewState for this control because it has appended this to your ViewState.

HQmFoYW1hcwdCYWhyYWluCkJhbmdsYWRlc2gIQmFyYmFkb3MIQmVsYXJ1cyAHQmVsZ2l1bQZCZWxpemUF
QmVuaW4HQmVybXVkYQZCaHV0YW4HQm9saXZpYQhCb3Rzd2FuYQ1Cb3V2ZXQgSXNsYW5kBkJyYXppbB5
Ccml0aXNoIEluZGlhbiBPY2VhbiBUZXJyaXRvcnkRQnJ1bmVpIERhcnVzc2FsYW0IQnVsZ2FyaWEMQnVya2luY
SBGYXNvB0J1cnVuZGkJQ2FtYm9kaWEgCENhbWVyb29uBkNhbmFkYQpDYXBlIFZlcmRlDkNheW1hbiBJc2xhb
mRzGENlbnRyYWwgQWZyaWNhbiBSZXB1YmxpYwRDaGFkBUNoaWxlBUNoaW5hEENocmlzdG1hcyBJc2xhbm
QOQ29jb3MgIElzbGFuZHMIQ29sb21iaWEHQ29tb3JvcwVDb25nbwVDb25nbwxDb29rIElzbGFuZHMKQ29zdGE
gUmljYQhDcm9hdGlhIARDdWJhBkN5cHJ1cw5DemVjaCBSZXB1YmxpYwdEZW5tYXJrCERqaWJvdXRpCERvbW
luaWNhEkRvbWluaWNhbiBSZXB1YmxpYwpFYXN0IFRpbW9yB0VjdWFkb3IFRWd5cHQLRWwgU2FsdmFkb3IRR
XF1YXRvcmlhbCBHdWluZWEHRXJpdHJlYQdFc3RvbmlhCEV0aGlvcGlhEkV1cm9wZWFuIENvbW11bml0eRFGY
WxrbGFuZCBJc2xhbmRzIA1GYXJvZSBJc2xhbmRzDEZpamkgSXNsYW5kcwdGaW5sYW5kBkZyYW5jZQZGcmFu
Y2UNRnJlbmNoIEd1aWFuYRBGcmVuY2ggUG9seW5lc2lhKUZyZW5jaCBTb3V0aGVybiBhbmQgQW50YXJjdGlj
IFRlcnJpdG9yaWVzBUdhYm9uBkdhbWJpYQdHZW9yZ2lhCEdlcm1hbnkgBUdoYW5hCUdpYnJhbHRhcgZHcmVl
Y2UJR3JlZW5sYW5kB0dyZW5hZGEKR3VhZGVsb3VwZQRHdWFtCUd1YXRlbWFsYQZHdWluZWEGR3V5YW5hB
UhhaXRpGkhlYXJkIGFuZCBNY0RvbmFsZCBJc2xhbmRzCUhvbHkgU2VlIAhIb25kdXJhcwlIb25nIEtvbmcISHJ2YX
Rza2EHSHVuZ2FyeQdJY2VsYW5kBUluZGlhCUluZG9uZXNpYQRJcmFuBElyYXEHSXJlbGFuZAZJc3JhZWwFSX
RhbHkMSXZvcnkgQ29hc3QgB0phbWFpY2EFSmFwYW4GSm9yZGFuCkthemFraHN0YW4FS2VueWEIS2lyaWJh
dGkFS29yZWEFS29yZWEGS3V3YWl0Ckt5cmd5enN0YW4hTGFvIFBlb3BsZSdzIERlbW9jcmF0aWMgUmVwdWJ
saWMgBkxhdHZpYQdMZWJhbm9uB0xlc290aG8HTGliZXJpYRZMaWJ5YW4gQXJhYiBKYW1haGlyaXlhDUxpZ
WNodGVuc3RlaW4JTGl0aHVhbmlhCkx1eGVtYm91cmcGTWFjYW8gCU1hY2Vkb25pYQpNYWRhZ2FzY2FyBk1
hbGF3aQhNYWxheXNpYQhNYWxkaXZlcwRNYWxpBU1hbHRhEE1hcnNoYWxsIElzbGFuZHMKTWFydGluaXF1Z
QpNYXVyaXRhbmlhCU1hdXJpdGl1cwdNYXlvdHRlBk1leGljbwpNaWNyb25lc2lhB01vbGRvdmEGTW9uYWNvCE
1vbmdvbGlhCk1vbnRzZXJyYXQHTW9yb2NjbwpNb3phbWJpcXVlCE15YW5tYXIgB05hbWliaWEFTmF1cnUFTm
VwYWwLTmV0aGVybGFuZHMUTmV0aGVybGFuZHMgQW50aWxsZXMNTmV3IENhbGVkb25pYQtOZXcgWmV
hbGFuZAlOaWNhcmFndWEFTmlnZXIHTmlnZXJpYQROaXVlDk5vcmZvbGsgSXNsYW5kGE5vcnRoZXJuIE1hcml
hbmEgSXNsYW5kcwZOb3J3YXkET21hbghQYWtpc3RhbgVQYWxhdQZQYW5hbWEQUGFwdWEgTmV3IEd1aW
5lYQhQYXJhZ3VheQRQZXJ1C1BoaWxpcHBpbmVzD1BpdGNhaXJuIElzbGFuZAZQb2xhbmQIUG9ydHVnYWwL
UHVlcnRvIFJpY28FUWF0YXIHUj91bmlvbgdSb21hbmlhElJ1c3NpYW4gRmVkZXJhdGlvbgZSd2FuZGEWU2Fpbn
QgS2l0dHMgIGFuZCBOZXZpcwtTYWludCBMdWNpYQ1TYWludCBWaW5jZW50BVNhbW9hClNhbiBNYXJpbm8
YU+KAmW8gVG9tPyBhbmQgUHLCrW5jaXBlDFNhdWRpIEFyYWJpYQdTZW5lZ2FsFlNlcmJpYSBhbmQgTW9ud
GVuZWdybyAKU2V5Y2hlbGxlcwxTaWVycmEgTGVvbmUJU2luZ2Fwb3JlCVNsb3Zha2lhIAhTbG92ZW5pYQ9Tb
2xvbW9uIElzbGFuZHMHU29tYWxpYQxTb3V0aCBBZnJpY2ENU291dGggR2VvcmdpYQVTcGFpbglTcmkgTGFu
a2EJU3QgSGVsZW5hFlN0IFBpZXJyZSBhbmQgTWlxdWVsb24FU3VkYW4IU3VyaW5hbWUeU3ZhbGJhcmQgYW
5kIEphbiBNYXllbiBJc2xhbmRzCVN3YXppbGFuZAZTd2VkZW4LU3dpdHplcmxhbmQUU3lyaWFuIEFyYWIgUmV
wdWJsaWMGVGFpd2FuClRhamlraXN0YW4IVGFuemFuaWEIVGhhaWxhbmQEVG9nbwdUb2tlbGF1BVRvbmdh
E1RyaW5pZGFkIGFuZCBUb2JhZ28HVHVuaXNpYQV1cmtleQt1cmttZW5pc3RhbhhUdXJrcyBhbmQgQ2FpY29zI
ElzbGFuZHMGVHV2YWx1BlVnYW5kYQdVa3JhaW5lI1VuaW9uIG9mIFNvdmlldCBTb2NpYWxpc3QgUmVwdWJs
aWNzFFVuaXRlZCBBcmFiIEVtaXJhdGVzDlVuaXRlZCBLaW5nZG9tGFVuaXRlZCBTdGF0ZXMgb2YgQW1lcmlj
YSRVbml0ZWQgU3RhdGVzIE1pbm9yIE91dGx5aW5nIElzbGFuZHMHVXJ1Z3VheQpVemJla2lzdGFuB1ZhbmF
1dHUSVmF0aWNhbiBDaXR5IFN0YXRlCVZlbmV6dWVsYQhWaWV0IE5hbQ9WaXJnaW4gSXNsYW5kcyAZV2Fsb
GlzIGFuZCBGdXR1bmEgSXNsYW5kcwtXZXN0IEFmcmljYQ5XZXN0ZXJuIFNhaGFyYQZZZW1lbiAGWmFtYmlhC
FppbWJhYndlFfEBAzI0NAMyNDUDMjQ2AzI0NwMyNDgDMjQ5AzI1MAMyNTEDMjUyAzI1MwMyNTQDMjU1AzI1
NgMyNTcDMjU4AzI1OQMyNjADMjYxAzI2MgMyNjMDMjY0AzI2NQMyNjYDMjY3AzI2OAMyNjkDMjcwAzI3MQMy
NzIDMjczAzI3NAMyNzUDMjc2AzI3NwMyNzgDMjc5AzI4MAMyODEDMjgyAzI4MwMyODQDMjg1AzI4NgMyODcD
Mjg4AzI4OQMyOTADMjkxAzI5MgMyOTMDMjk0AzI5NQMyOTYDMjk3AzI5OAMyOTkDMzAwAzMwMQMzMDID
MzAzAzMwNAMzMDUDMzA2AzMwNwMzMDgDMzA5AzMxMAMzMTEDMzEyAzMxMwMzMTQDMzE1AzMxNg
MzMTcDMzE4AzMxOQMzMjADMzIxAzMyMgMzMjMDMzI0AzMyNQMzMjYDMzI3AzMyOAMzMjkDMzMwAzMz
MQMzMzIDMzMzAzMzNAMzMzUDMzM2AzMzNwMzMzgDMzM5AzM0MAMzNDEDMzQyAzM0MwMzNDQDMzQ
1AzM0NgMzNDcDMzQ4AzM0OQMzNTADMzUxAzM1MgMzNTMDMzU0AzM1NQMzNTYDMzU3AzM1OAMzNTk
DMzYwAzM2MQMzNjIDMzYzAzM2NAMzNjUDMzY2AzM2NwMzNjgDMzY5AzM3MAMzNzEDMzcyAzM3MwMzN
zQDMzc1AzM3NgMzNzcDMzc4AzM3OQMzODADMzgxAzM4MgMzODMDMzg0AzM4NQMzODYDMzg3AzM4O
AMzODkDMzkwAzM5MQMzOTIDMzkzAzM5NAMzOTUDMzk2AzM5NwMzOTgDMzk5AzQwMAM0MDEDNDAyAz
QwMwM0MDQDNDA1AzQwNgM0MDcDNDA4AzQwOQM0MTADNDExAzQxMgM0MTMDNDE0AzQxNQM0MTY
DNDE3AzQxOAM0MTkDNDIwAzQyMQM0MjIDNDIzAzQyNAM0MjUDNDI2AzQyNwM0MjgDNDI5AzQzMAM0MzE
DNDMyAzQzMwM0MzQDNDM1AzQzNgM0MzcDNDM4AzQzOQM0NDADNDQxAzQ0MgM0NDMDNDQ0AzQ0NQ
M0NDYDNDQ3AzQ0OAM0NDkDNDUwAzQ1MQM0NTIDNDUzAzQ1NAM0NTUDNDU2AzQ1NwM0NTgDNDU5Az
Q2MAM0NjEDNDYyAzQ2MwM0NjQDNDY1AzQ2NgM0NjcDNDY4AzQ2OQM0NzADNDcxAzQ3MgM0NzMDNDc0
AzQ3NQM0NzYDNDc3AzQ3OAM0NzkDNDgwAzQ4MQM0ODIDNDgzAzQ4NBQrA/EBZ2dnZ2dnZ2dnZ2dnZ2dnZ
2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dn
Z2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2d
nZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2
dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZxYBAmdkAgsPD2QWAh4HQ291bnRyeQUDMzQ3FgICBA8PF
gQfAAUOUGl4ZWxfT3B0aW9ucyAfAQICFgIeBXN0eWxlBSV2aXNpYmlsaXR5OmhpZGRlbjsgcG9zaXRpb246Y
WJzb2x1dGU7FgICAw9kFgJmD2QWBmYPZBYCZg8PZBYCHgVjbGFzcwUNT3B0aW9uX0J1dHRvbhYCZg9kFgR
mDw8WAh4ISW1hZ2VVcmwFMX4vQWRtaW4vUGl4ZWxQcmVzc19Db21tb24vaW1hZ2VzL0J1dHRvbnMvVmlld
y5naWZkZAIBDxYCHglpbm5lcmh0bWwFBFZpZXdkAgEPZBYCZg8PZBYCHwUFDU9wdGlvbl9CdXR0b24WAmY
PZBYEZg8PFgIfBgUxfi9BZG1pbi9QaXhlbFByZXNzX0NvbW1vbi9pbWFnZXMvQnV0dG9ucy9FZGl0LmdpZmRk
AgEPFgIfBwUERWRpdGQCAg9kFgJmDw9kFgIfBQUNT3B0aW9uX0J1dHRvbhYCZg9kFgRmDw8WAh8GBTN+L0
FkbWluL1BpeGVsUHJlc3NfQ29tbW9uL2ltYWdlcy9CdXR0b25zL0RlbGV0ZS5naWZkZAIBDxYCHwcFBkRlbGV0Z
WQYAQUlY3RsMDAkbWFpbkNvbnRlbnQkdWNSZWdpb25zJGd2UmVnaW9ucw88KwAJAQgCAmQ2NMQOfEq2i
6VNUkJC0rdxgGU34g


Although it flies down on your localhost, the dropdownlist’s ViewState will greatly increase your page download time on the web especially if you have a number of these controls. You want a simple solution to be able to remove this ViewState added by your Dropdownlist while maintaining your postback events, i.e. A Dropdownlist without the ViewState.

The Reason

The reason this happens is simple. The primary use of ViewState is to maintain control “instances” when posting back. When you bound your DropdownList you most likely did something like follows. 

public void BindCountryDropDown()
{
    if (!Page.IsPostBack)
    {
        ddlCountrySelect.DataSource = CountryDAL.AllCountries;
        ddlCountrySelect.DataBind();
 
        if (ddlCountrySelect.Items.FindByValue(CurrentCountry.CountryId.ToString()) != null)
        {
            ddlCountrySelect.ClearSelection();
            ddlCountrySelect.Items.FindByValue
            CurrentCountry.CountryId.ToString()).Selected = true;
        }
    }
}


You specified that when posting back, do not populate the DropdownList.
You did this for 1 reason. If you didn’t put the famous !Page.IsPostBack your DropdownList’s SelectedValue would never change.
There is actually a second reason...you don’t have to bind the data on postback.



Look at my Watch above on postback. Even though I didn’t bind the control on postback, I still have my 241 ListItems. As you have probably guessed, this is down to the ViewState. ViewState (transparently) gives us the impression that the application has been waiting for your response.
It does this by remembering what data you had to prior to postback. Why does it remember?

Well take your DropdownList. On Postback the first thing your application does is De-Serialise your DropdownList from the ViewState. The result is the exact Dropdownlist that you rendered.
Then the application retrieves 

string selectedValue = HttpContext.Current.Request.Form[UniqueID];

This would retrieve your submitted value.

From here the DropdownList just does a 

ClearSelection();
Items.FindByValue(selectedValue).Selected = true;

Now you have a new SelectedValueSelectedIndex and SelectedItem. Therefore your selected Index has changed and your events will be fired.
With ViewState disabled your DropdownList is never De-Serialised/Populated and your Items collection will be always be empty. Your SelectedIndex will always be Zero which means your OnSelectedIndexChanged event will never be fired. Even if it was fired your SelectedIndex will be 0 and your SelectedItem will always be null.

The Solution

There are many solutions to the problem most of them are a bit messy and time consuming. The best solution is to simply create your own DropDownList WebControl. Don’t worry its not as daunting as you think...
This is the complete code you need. 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.IO;
using System.Collections.Specialized;
using System.Xml.Serialization;
using System.Collections;
 
using System.Reflection;
using PixelPress.Common.Web;
 
namespace PixelPress.Interface.WebControls
{
    public class PixelDropDownList : DropDownList, IPostBackEventHandler
    {
 
        public override string SelectedValue
        {
            get
            {
                if (!EnableViewState && Page.IsPostBack)
                {
                    string selectedValue = HttpContext.Current.Request.Form[UniqueID];
                    
                    if (selectedValue != null)
                    {
                        
                        // Then we get our selected Item
                        return selectedValue;
                    }
                    else
                    {
                        return base.SelectedValue;
                    }
                }
                else
                {
                    return base.SelectedValue;
                }
            }
            set
            {
                base.SelectedValue = value;
            }

       }
 
 
 
        public void RaisePostBackEvent(string eventArgument)
        {
            // If the Viewstate is disabled we retrieve our selected index from the Form 
           if (!EnableViewState && Page.IsPostBack)
           {
 
                OnSelectedIndexChanged(new EventArgs());
           }
        }

   }

 

 

All we are doing essentially is interfering with the ASP: DROPDOWNLIST when the ViewState is disabled. The DropdownList will work as normal when the ViewState is enabled.
When the ViewState is disabled we simply make sure that the OnSelectedIndexChanged event is fired when a Postback event is raised. To do this we add interface member RaisePostBackEvent to accompany RaisePostDataChangedEvent. In RaisePostBackEvent we just make sure that our OnSelectedIndexChanged is called.

Then we ensure that the SelectedValue returns the submitted value.

However, your ListItems will still be empty and SelectedIndex and SelectedItem will still be null, you will just be able to refer to SelectedValue.

That’s it, simply

  1. Create a new CS file in your class library, name it what you like.
  2. Paste the above into your file and compile your Class Library
  3. Go to the page/control using the new DropdownList
  4. Register your new control. See below PixelPress_Lib is the name of your Assembly; PixelPress.Interface.WebControls is the namespace that your control is compiled under.  
  5. To use on your page just do as you did with a ASP:DROPDOWNLIST

An example of it in use on your page 

<%@ register
    tagprefix="pixel" 
    namespace="PixelPress.Interface.WebControls" 
    assembly
="PixelPress_Lib" 
%>

 

 

 

 

 

<h1> Country and Region Manager</h1>

 The following are all of teh regions associated with

<pixel:pixeldropdownlist
id="ddlCountrySelect"
runat="server"
enableviewstate="false"
autopostback="true"
datavaluefield="CountryId"
datatextfield="CountryTitle"
onselectedindexchanged="ddlCountrySelect_SelectedIndexChanged" />

 

 

 

On a final note, I have heard suggestions to use the SessionState to persist the state of the DropdownList. This would be a huge waste of SessionState and server memory. Don’t consider it as an option..

Thanks for reading.

Published by

Paul Tierney
Senior Software Engineer
Harvard Development Galway (HDG)