Question

I have a fairly simple page with a set of jQuery tabs, the content of some is called via ajax. I also have a search box in the masterpage in my header.

When I open the tabbed page the search box works fine. However once I have clicked on one of the ajax tabs the search box fails to work with an "Invalid Viewstate" yellow screen of death.

I believe this is because the ajax page is replacing the __VIEWSTATE hidden input with its own.

How can I stop this behaviour?

UPDATE: I have noticed that the YSOD only appears in IE and Chrome, Firefox doesn't seem to have the same issue. Although how the browser influences the ViewState, I'm not sure.

UPDATE: I've put a cut down version of the site that shows the issue here: http://dropbox.com/s/7wqgjqqdorgp958/stackoverflow.zip

Was it helpful?

Solution

The reason of such behavior is that you getting content of the ajaxTab.aspx page asynchronously and paste it into another aspx page. So you getting two instances of hidden fields with __VIEWSTATE name and when page posted back to server theirs values are mixing (might depends on how browser process multiple controls with same name on submit). To resolve this you can put second tab's content into a frame:

 <div id="tabs">
      <ul>
           <li><a href="#tabs-1">Default Tab</a></li>
           <li><a href="#tabs-2">ajax Content</a></li>
      </ul>
      <div id="tabs-1">
           <p>
                To replicate the error:
                <ul>
                     <li>First use the search box top right to search to prove that code is ok</li>
                     <li>Then click the second ajax tab, and search again.</li>
                     <li>N.B. Chrome / IE give a state error, Firefox does not</li>
                </ul>
           </p>
      </div>
      <iframe id="tabs-2" src="ajaxTab.aspx" style="width:100%;" ></iframe>
 </div>

Also, I'm not sure but this seems like error in the Web_UserControls_search control. In my opinion, NavBarSearchItemNoSearchItem_OnClick method must be refactored as below:

protected void NavBarSearchItemNoSearchItem_OnClick(object sender, EventArgs e)
{
    var searchFieldTbx = NavBarSearchItemNo;
    var navBarSearchCatHiddenField = NavBarSearchCatHiddenField;

    var term = searchFieldTbx != null ? searchFieldTbx.Text : "";

    if (term.Length > 0) //There is actually something in the input box we can work with
    {
        //Response.Redirect(Url.GetUrl("SearchResults", term));
        Response.Redirect(ResolveClientUrl("~/Web/SearchResults.aspx?term=" + term + "&cat=" + navBarSearchCatHiddenField.Value));
    }
}

Draw attention that we resolving client url when redirecting to search results page and instead of navBarSearchCatHiddenField use navBarSearchCatHiddenField.Value as cat parameter.

OTHER TIPS

I guess that you use AJAX to fill the content of the tab. So in this case, content of your tab will be replaced by the new one from ajax and certainly _VIEWSTATE will be replaced. At server, do you use data from ViewState? In the "static tabs", you should prevent them auto reload by using cache:true

Your issue is that with your ajax call you bring in a complete ASPX page. Including the Form tag and its Viewstate. If you remove the Form tag from ajaxTab.aspx you will see everything works fine. asp.net does not know how to handle two Form tags in one page. Same goes for hidden Viewstate fields. You cannot bring in a full aspx page via ajax. Just bring in the content Div you want to display and you`ll be good to go.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top