ViewStateException with DropDownListAdapter

I get this error 500:

Sys.WebForms.PageRequestManagerServerErrorException: An unknown error occurred while processing the request on the server. The status code returned from the server was: 500

UPDATE:

My mistake is actually: System.Web.UI.ViewStateException

 if (viewStates.Length != list.Items.Count + 1) { throw new ViewStateException(); } 

I’ve been getting it since I added this adapter to my site, which is shown in this tutorial.

ASP.NET DropDownList with OptionGroup support

It loads DropDownList simply on all pages, but when I make any callbacks, regular or ajax - this is when an error occurs. Here is my exact code for the adapter and browser file.

Adapter class

 public class DropDownListAdapter : WebControlAdapter { private const string OptionGroupAttribute = "OptionGroup"; private const string TagOptionGroup = "optgroup"; private const string AttributeLabel = "label"; protected override void RenderContents(HtmlTextWriter writer) { DropDownList list = Control as DropDownList; string currentOptionGroup; List<string> renderedOptionGroups = new List<string>(); foreach (ListItem item in list.Items) { Page.ClientScript.RegisterForEventValidation( list.UniqueID, item.Value); if (item.Attributes[OptionGroupAttribute] == null) { RenderListItem(item, writer); } else { currentOptionGroup = item.Attributes[OptionGroupAttribute]; if (renderedOptionGroups.Contains(currentOptionGroup)) { RenderListItem(item, writer); } else { if (renderedOptionGroups.Count > 0) { RenderOptionGroupEndTag(writer); } RenderOptionGroupBeginTag(currentOptionGroup, writer); renderedOptionGroups.Add(currentOptionGroup); RenderListItem(item, writer); } } } if (renderedOptionGroups.Count > 0) { RenderOptionGroupEndTag(writer); } } private void RenderOptionGroupBeginTag(string name, HtmlTextWriter writer) { writer.AddAttribute(AttributeLabel, name); writer.RenderBeginTag(TagOptionGroup); } private void RenderOptionGroupEndTag(HtmlTextWriter writer) { writer.RenderEndTag(); } private void RenderListItem(ListItem item, HtmlTextWriter writer) { foreach (string key in item.Attributes.Keys) { if (key != OptionGroupAttribute) { writer.AddAttribute(key, item.Attributes[key]); } } writer.AddAttribute(HtmlTextWriterAttribute.Value, item.Value, true); if (item.Selected) { writer.AddAttribute(HtmlTextWriterAttribute.Selected, "selected"); } writer.RenderBeginTag(HtmlTextWriterTag.Option); writer.WriteEncodedText(item.Text); writer.RenderEndTag(); } protected override object SaveAdapterViewState() { DropDownList list = Control as DropDownList; object[] viewStates = new object[list.Items.Count + 2]; int i = 0; foreach (ListItem item in list.Items) viewStates[i++] = item.Attributes[OptionGroupAttribute]; viewStates[i++] = base.SaveAdapterViewState(); viewStates[i] = Hash(list.Items); return viewStates; } private static int Hash(ListItemCollection listItems) { int hash = 0; foreach (ListItem listItem in listItems) hash += listItem.GetHashCode(); return hash; } object[] viewStates; protected override void LoadAdapterViewState(object state) { viewStates = (object[])state; base.LoadAdapterViewState(viewStates[viewStates.Length - 1]); } protected override void OnPreRender(System.EventArgs e) { if (viewStates != null && viewStates.Length > 1) { DropDownList list = Control as DropDownList; if (Page.EnableEventValidation) { if (viewStates.Length != list.Items.Count + 1) { throw new ViewStateException(); } } if (Hash(list.Items) == (int)viewStates[viewStates.Length - 1]) { int max = viewStates.Length - 2; if (list.Items.Count < max) { max = list.Items.Count; } for (int i = 0; i < max; i++) { list.Items[i].Attributes[OptionGroupAttribute] = (string)viewStates[i]; } } } base.OnPreRender(e); } } 

Browser File:

 <browsers> <browser refID="default"> <controlAdapters> <adapter controlType="System.Web.UI.WebControls.DropDownList" adapterType="DropDownListAdapter" /> </controlAdapters> </browser> </browsers> 

Stacktrace

 NopSolutions.NopCommerce.Web.DropDownListAdapter.OnPreRender(EventArgs e) in ... // I'm guessing the issue is here System.Web.UI.Control.PreRenderRecursiveInternal() +8948774 System.Web.UI.Control.PreRenderRecursiveInternal() +175 System.Web.UI.Control.PreRenderRecursiveInternal() +175 System.Web.UI.Control.PreRenderRecursiveInternal() +175 System.Web.UI.Control.PreRenderRecursiveInternal() +175 System.Web.UI.Control.PreRenderRecursiveInternal() +175 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2496 

If someone can point me in the right direction on how to fix this, that would be awesome. Now, please do not tell me to disable validateRequest , because this does not solve the problem, which it just closes.

+4
source share
1 answer

You probably already solved this problem or just went the other way, but for reference in the future.

In SaveAdapterViewState you save the state to an array of objects with length x + 2 :

 object[] viewStates = new object[list.Items.Count + 2]; 

Then, in LoadAdapterViewState you initialize the local viewStates field with an array of objects coming from the view state:

 viewStates = (object[])state; 

Finally, in OnPreRender you guarantee that the local viewStates field has a length of x + 1 , which will fail because you saved an array of length x + 2 and what you get when loading it from the view state.

+3
source

All Articles