Showing posts with label exception. Show all posts
Showing posts with label exception. Show all posts

Wednesday, March 28, 2012

Dynamic Ajax Tab Container raises unhandled exception: Specified argument was out of the r

Hi -

I've a problem with the ajax tab container: I try to add additional ajax tab panels dynamically at run time. This works fine, but as soon as I do it, any button I click on the page throws the exception below.

So, if I comment these 2 lines out:

Dim tpAsNew AjaxControlToolkit.TabPanel

Me.TCSpecialties.Tabs.Add(tp)

everything works fine (TCSpecialties is a Tab Container). Once I leave them in, this exception is thrown:

Specified argument was out of the range of valid values.
Parameter name: value

Description:An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details:System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: value

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.


Stack Trace:

[ArgumentOutOfRangeException: Specified argument was out of the range of valid values.Parameter name: value] AjaxControlToolkit.TabContainer.set_ActiveTabIndex(Int32 value) +381 AjaxControlToolkit.TabContainer.LoadClientState(String clientState) +160 AjaxControlToolkit.ScriptControlBase.LoadPostData(String postDataKey, NameValueCollection postCollection) +73 AjaxControlToolkit.TabContainer.LoadPostData(String postDataKey, NameValueCollection postCollection) +32 AjaxControlToolkit.ScriptControlBase.System.Web.UI.IPostBackDataHandler.LoadPostData(String postDataKey, NameValueCollection postCollection) +11 System.Web.UI.Page.ProcessPostData(NameValueCollection postData, Boolean fBeforeLoad) +718 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3776

Does anyone have a clue as to what may be going on??

Any help highly appreciated

I think you need to set the activetab which is null

somthing like TCSpecialties.ActiveTab = tp

This will set the active tab to the newly added tab.


I did that - still the same behavior as before. The tabs get displayed correctly, as a matter of fact. Any ideas?


By "adding tabs dynamically at runtime" are you doing this client side or server side? Can you file a bug at codeplex at attach a simple repro?


I am doing this on the server side ... what I meant is that the controls are not dropped in the form at designtime but rather created based on database fields (one Tab per record, with 3 records in the database). Will try to create a repro


You may need to recreate the tab panels when the postback occurs in the Page_init because the tabpanels do not exist on post backs until they have been made...

So in Page_init you should call a function that makes the default tab collection and then later on the page you can add a new tab panel to the collection.

Hope this makes sense.


That fixed itSmile

Thanks very much!!!!

Oliver


Thanks guys for the thread. It has saved us HEAPS of time.

After reading it though I still had a few problems getting it to work (which it is now).
These are probably pretty obvious to most of you out there, but it may be helpful for those reading this thread that still can't get it working.

We are now creating the tabbed panels dynamically in Page_Init as instructed.
One thing we did wrong was to only do this if it was not a postback. In hindsight we obviously we needed to do this all the time.

Also for those who are wondering how to save the selected values on the page if you are recreating the tab panels everytime, I think that the save view state and load view state events are doing this for you automatically; I think they just need to have the controls created (which you are now doing in page_init) and then they will do the rest.

Isn't life grand :)

Thanks again for sharing this info with everyone.

Mark


Can you please post a code example here of what must be written inside the page_init function ?


Just create whatever dynamic controls you have. If you add a text box with the ID="tb1" dynamically (I know, it's more likely you created something data driven), just add the following

dim l as new textbox

l.id="tb1"

me.page.controls.add(l)

That's it. Just do this for any controls you added. Note: Do not reset the values, viewstate will take care of that for you.

Now, you can simply access the text property somewhere else in your code behind as

l.text

and it will have the text the user entered. Hope that helps


Hello,

I am doing it according to this post but still getting "Index out of range" exception when I try to add a second TabPanel by clicking a button...

Any ideas?...

public partial class TestPage : System.Web.UI.Page
{
private TabContainer _tabContainer;

protected void Page_Init(object sender, EventArgs e)
{
_tabContainer = new TabContainer();
_tabContainer.Height = Unit.Pixel(250);

TabPanel tab = new TabPanel();
tab.HeaderText = "New Tab 1";

_tabContainer.Tabs.Add(tab);

tab = new TabPanel();
tab.HeaderText = "New Tab 2";

_tabContainer.Tabs.Add(tab);
_tabContainer.ActiveTab = tab;

ContainerPanel.Controls.Add(_tabContainer);
}
protected void Button1_AddTab(object sender, EventArgs e)
{
TabPanel tab = new TabPanel();
tab.HeaderText = "New Tab 3";

_tabContainer.Tabs.Add(tab);
_tabContainer.ActiveTab = tab;
}
}


Hey can you clarify the sentence:

"

So in Page_init you should call a function that makes the default tab collection and then later on the page you can add a new tab panel to the collection."

What's a default tab collection? I'm having the same problem and I don't really understand the solution.

Thanks


I can't really clarify better than I did before... Just look at the code I posted and you'll understand...

Thanks,

David


Can some please explain what is the reason behind this error?

Is it a feature or a bug?

I thank all for the answers, but eventually they either unclear or imply that if I want to add tabs dynamically then I have to create all the other controls on page dynamically (which seems to me somehow unpractical if I have a control rich page).

Any ideas?


This is what I found as a solution to this mess.

Assume you have a TabContainer with a TabPanel at design time. You also have a button which when clicked adds a new TabPanel to the TabContainer at runtime.

On postback, every TabPanel already added dynamically must be recreated before the Button_Click and the Page_Load are processed. In other words, this applies to all TabPanels except for the first one. This can be done in the Page_Init handler which I do not recommend for a very good reason: As soon as you mess with it you have to recreateall other dynamic controls your page may contain!

On the other hand, the TabContainer control has an Init handler itself so why not use it insteadWink

The following example adds a new TabPanel every time the button is clicked. Each tab has a header "Tab X" where X = 1 ... tabIndexName. You also need the tabIndexName static member to keep count of how many TabPanels have been created so far. Last but not least, have in mind that you cannot use the ViewState object inside the Init method.

public partialclass TabContainerTest : System.Web.UI.Page
{
public static int tabIndexName;

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
tabIndexName = 2;
}
}

protected void Button1_Click(object sender, EventArgs e)
{
AjaxControlToolkit.TabPanel tab =new AjaxControlToolkit.TabPanel();
tab.HeaderText ="Tab " + Convert.ToString(tabIndexName++);
TabContainer1.Tabs.Add(tab);
}

protected void TabContainer1_Init(object sender, EventArgs e)
{
if (IsPostBack)
{
for (int i = 1; i < tabIndexName - 1; i++)
{
AjaxControlToolkit.TabPanel tab =new AjaxControlToolkit.TabPanel();
tab.HeaderText ="Tab " + Convert.ToString(i + 1);
TabContainer1.Tabs.Add(tab);
}
}
}
}

Hope this helps.

Monday, March 26, 2012

DummyHtmlTextWriter Exception

Hi All,

I am getting the following exception using the April CTP:

System.Exception was unhandled by user code Message="An instance of 'Microsoft.Web.UI.DummyHtmlTextWriter' could not be used as an HtmlTextWriter. Make sure the specified class can be instantiated, extends System.Web.UI.HtmlTextWriter, and implements a constructor with a single parameter of type System.IO.TextWriter." Source="App_Web_sqmaviya" StackTrace: at Forms_Coordinators_AwardPoints.scriptManager_PageError(Object sender, PageErrorEventArgs e)in c:\Documents and Settings\jyoung\My Documents\Visual Studio 2005\WebSites\Pointfolio_v2\Forms\Coordinators\AwardPoints.aspx.cs:line 188 at Microsoft.Web.UI.ScriptManager.OnPageError(PageErrorEventArgs e) at Microsoft.Web.UI.ScriptManager.OnPageError(Exception ex) at Microsoft.Web.UI.ScriptManager.RenderPageCallback(HtmlTextWriter writer, Control pageControl) at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) at System.Web.UI.Control.Render(HtmlTextWriter writer) at System.Web.UI.Page.Render(HtmlTextWriter writer) at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) at System.Web.UI.Control.RenderControl(HtmlTextWriter writer) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
This has proven to be very difficult to replicate as it seems completely random.
I have a web user control that contains a TreeView and 2 GridViews (available and selected).
Think file explorer with folders in the tree, files in one gridview and files that have been selected (via available) in the second gridview.
Both gridviews are wrapped in updatepanels with available triggering off the treeview and the selected triggering off the command of available.
The above exception gets thrown at random points when the triggers are fired.
I say random, because I can replicate the error, but not in an orderly fashion.
I go through selecting and deselecting and everything works fine and then boom exception.
Any help or insight would be greatly appreciated.

I tried the June CTP with the same issues.


In the hopes that this was an issue with the local dev server that is built into VS, I tried this under IIS6 with the same exception.

I am growing very discouraged by this. I ditched a custom built AJAX implementation in favor of Atlas and am now thinking that I have to ditch Atlas and go back to my implementation. I REALLY REALLY don't want to do this, but I don't know how to get around the exception.

I tried swallowing the exception but then I can an "Unknown Error" alert and then the whole thing blows up.

The aspx markup and codebehind is a bit long, but I can post it if you think it will help.

If this is an exception that I can do nothing about, is there anyway to swallow it and have it keep working without having to refresh the page?

I could really use the help on this one.

Thanks,

Joe


Hi,

two questions:

1) are you handling the PageError event of the ScriptManager?
2) are you using cache?

Hi, I am using the PageErrorEvent

protected void scriptManager_PageError(object sender, Microsoft.Web.UI.PageErrorEventArgs e) {throw new Exception(e.ErrorMessage); }
There is no caching at this page. There is some cache use in other parts of the application.

I take it there is some issue between Atlas and Output Caching and if we use one we can't use the other? What are the issues? Can you point me to a resource where there is more information?


I created a test project and was able to replicate the error.
It seems to have to due something with output caching. I added a webusercontrol and enabled output caching on it and got the error.
I can't upload my test solution so I will show all the code.

Web.Config
<configuration>
<!--
The configSections define a section for ASP.NET Atlas.
-->
<configSections>
<sectionGroup name="microsoft.web" type="Microsoft.Web.Configuration.MicrosoftWebSectionGroup">
<section name="converters" type="Microsoft.Web.Configuration.ConvertersSection" />
<section name="webServices" type="Microsoft.Web.Configuration.WebServicesSection" />
<section name="authenticationService" type="Microsoft.Web.Configuration.AuthenticationServiceSection" />
<section name="profileService" type="Microsoft.Web.Configuration.ProfileServiceSection" />
</sectionGroup>
</configSections
<!--
The microsoft.web section defines items required for the Atlas framework.
-->
<microsoft.web>
<converters>
<add type="Microsoft.Web.Script.Serialization.Converters.DataSetConverter"/>
<add type="Microsoft.Web.Script.Serialization.Converters.DataRowConverter"/>
<add type="Microsoft.Web.Script.Serialization.Converters.DataTableConverter"/>
</converters>
<webServices enableBrowserAccess="true" />
</microsoft.web>

<appSettings/>
<connectionStrings/>

<system.web>
<pages>
<controls>
<add namespace="Microsoft.Web.UI" assembly="Microsoft.Web.Atlas" tagPrefix="atlas"/>
<add namespace="Microsoft.Web.UI.Controls" assembly="Microsoft.Web.Atlas" tagPrefix="atlas"/>
</controls>
</pages>
<compilation debug="false">
<buildProviders>
<add extension=".asbx" type="Microsoft.Web.Services.BridgeBuildProvider" />
</buildProviders>
</compilation>
<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx" type="Microsoft.Web.Services.ScriptHandlerFactory" validate="false"/>
<!--
The MultiRequestHandler enables multiple requests to be handled in one
roundtrip to the server. Its use requires Full Trust.
-->
<add verb="*" path="atlasbatchcall.axd" type="Microsoft.Web.Services.MultiRequestHandler" validate="false"/>
<add verb="*" path="atlasglob.axd" type="Microsoft.Web.Globalization.GlobalizationHandler" validate="false"/>
<!--
The IFrameHandler enables a limited form of cross-domain calls to 'Atlas' web services.
This should only be enabled if you need this functionality and you're willing to expose
the data publicly on the Internet.
To use it, you will also need to add the attribute [WebOperation(true, ResponseFormatMode.Json, true)]
on the methods that you want to be called cross-domain.
This attribute is by default on any DataService's GetData method.

<add verb="*" path="iframecall.axd" type="Microsoft.Web.Services.IFrameHandler" validate="false"/>
-->
<add verb="*" path="*.asbx" type="Microsoft.Web.Services.ScriptHandlerFactory" validate="false"/>
</httpHandlers>
<httpModules>
<add name="ScriptModule" type="Microsoft.Web.Services.ScriptModule"/>
<add name="BridgeModule" type="Microsoft.Web.Services.BridgeModule"/>
<add name="WebResourceCompression" type="Microsoft.Web.Services.WebResourceCompressionModule"/>
</httpModules>
<authentication mode="Windows" />
</system.web>
</configuration>

ASPX Page
<%@. Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="AtlasTest._Default" %
<%@. register src="http://pics.10026.com/?src=WebUserControl1.ascx" tagname="WebUserControl1" tagprefix="uc1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<atlas:scriptmanager id="scriptManager" runat="server" enablepartialrendering="true" onpageerror="scriptManager_PageError"></atlas:scriptmanager>
<asp:treeview id="TreeView1" runat="server" onselectednodechanged="TreeView1_SelectedNodeChanged">
</asp:treeview>
<atlas:updatepanel id="updatePanel1" runat="server" mode="Conditional">
<contenttemplate>
<asp:gridview id="GridView1" runat="server" backcolor="White" bordercolor="#CC9966" borderstyle="None" borderwidth="1px" cellpadding="4" autogeneratecolumns="False" autogenerateselectbutton="True" onselectedindexchanged="GridView1_SelectedIndexChanged">
<footerstyle backcolor="#FFFFCC" forecolor="#330099" />
<rowstyle backcolor="White" forecolor="#330099" />
<selectedrowstyle backcolor="#FFCC66" font-bold="True" forecolor="#663399" />
<pagerstyle backcolor="#FFFFCC" forecolor="#330099" horizontalalign="Center" />
<headerstyle backcolor="#990000" font-bold="True" forecolor="#FFFFCC" />
<columns>
<asp:boundfield headertext="Id" datafield="Id" />
<asp:boundfield headertext="Name" datafield="Name" />
</columns>
</asp:gridview>
</contenttemplate>
<triggers>
<atlas:controleventtrigger controlid="TreeView1" eventname="SelectedNodeChanged" /></triggers>
</atlas:updatepanel>
</div>
<uc1:webusercontrol1 id="WebUserControl1_1" runat="server" />
</form>
</body>
</html>

Code Behind
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace AtlasTest
{
public partialclass _Default : System.Web.UI.Page
{
private Dictionary<int, Group> groupDictionary;

protected void Page_Load(object sender, EventArgs e)
{
CreateGroups();

if (!Page.IsPostBack)
{
BindGroupTree(groupDictionary[1],null);
}
}

private void CreateGroups()
{

groupDictionary =new Dictionary<int, Group>();

Group root =new Group(1,"Root");
Group child1 =new Group(2,"Child1");
Group child2 =new Group(3,"Child2");
Group child11 =new Group(4,"Child11");
Group child12 =new Group(5,"Child12");
Group child21 =new Group(6,"Child21");
Group child22 =new Group(7,"Child22");

groupDictionary.Add(root.Id, root);
groupDictionary.Add(child1.Id, child1);
groupDictionary.Add(child2.Id, child2);
groupDictionary.Add(child11.Id, child11);
groupDictionary.Add(child12.Id, child12);
groupDictionary.Add(child21.Id, child21);
groupDictionary.Add(child22.Id, child22);

// Build the tree
root.Children.Add(child1.Id, child1);
root.Children.Add(child2.Id, child2);

child1.Children.Add(child11.Id, child11);
child1.Children.Add(child12.Id, child12);

child2.Children.Add(child21.Id, child21);
child2.Children.Add(child22.Id, child22);

child1.Users.Add(new User(11,"Test 11"));
child1.Users.Add(new User(12,"Test 12"));
child1.Users.Add(new User(13,"Test 13"));
child1.Users.Add(new User(14,"Test 14"));
child1.Users.Add(new User(15,"Test 15"));

child2.Users.Add(new User(21,"Test 21"));
child2.Users.Add(new User(22,"Test 22"));
child2.Users.Add(new User(23,"Test 23"));
child2.Users.Add(new User(24,"Test 24"));
child2.Users.Add(new User(25,"Test 25"));

child11.Users.Add(new User(111,"Test 111"));
child11.Users.Add(new User(112,"Test 112"));
child11.Users.Add(new User(113,"Test 113"));
child11.Users.Add(new User(114,"Test 114"));
child11.Users.Add(new User(115,"Test 115"));

child12.Users.Add(new User(121,"Test 121"));
child12.Users.Add(new User(122,"Test 122"));
child12.Users.Add(new User(123,"Test 123"));
child12.Users.Add(new User(124,"Test 124"));
child12.Users.Add(new User(125,"Test 125"));

child21.Users.Add(new User(211,"Test 211"));
child21.Users.Add(new User(212,"Test 212"));
child21.Users.Add(new User(213,"Test 213"));
child21.Users.Add(new User(214,"Test 214"));
child21.Users.Add(new User(215,"Test 215"));

child22.Users.Add(new User(221,"Test 221"));
child22.Users.Add(new User(222,"Test 222"));
child22.Users.Add(new User(223,"Test 223"));
child22.Users.Add(new User(224,"Test 224"));
child22.Users.Add(new User(225,"Test 225"));
}

private void BindGroupTree(Group group, TreeNode parent)
{
if (group.Children ==null) {return; }

foreach (KeyValuePair<int, Group> kvpin group.Children)
{
TreeNode treeNode =new TreeNode();
treeNode.Value = kvp.Key.ToString();
treeNode.Text = kvp.Value.Name;

if (parent ==null)
{
TreeView1.Nodes.Add(treeNode);
}
else
{
parent.ChildNodes.Add(treeNode);
}

BindGroupTree(kvp.Value, treeNode);
}
}

protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e)
{
int selectedIndex = System.Convert.ToInt32(TreeView1.SelectedValue);

List users = groupDictionary[selectedIndex].Users;

GridView1.DataSource = users;
GridView1.DataBind();
}

protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{

}

protected void scriptManager_PageError(object sender, Microsoft.Web.UI.PageErrorEventArgs e)
{
throw new Exception(e.ErrorMessage);
}
}
}

Data
using System;
using System.Data;
using System.Configuration;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace AtlasTest
{
public class Group
{
private int id;
private string name;
private Dictionary<int, Group> children;
private List users;

public int Id
{
get {return this.id; }
set {this.id =value; }
}

public string Name
{
get {return this.name; }
set {this.name =value; }
}

public Dictionary<int, Group> Children
{
get {return this.children; }
}

public List Users
{
get {return this.users; }
}

public Group(int id,string name)
{
this.id = id;
this.name = name;
this.children =new Dictionary<int, Group>();
this.users =new List();
}
}

public class User
{
private int id;
private string name;

public int Id
{
get {return this.id; }
set {this.id =value; }
}

public string Name
{
get {return this.name; }
set {this.name =value; }
}

public User(int id,string name)
{
this.id = id;
this.name = name;
}
}
}

WebUserControl
<%@. Control Language="C#" AutoEventWireup="true" CodeBehind="WebUserControl1.ascx.cs" Inherits="AtlasTest.WebUserControl1" %>
<%@. outputcache duration="5" varybyparam="none" %>
<asp:datalist id="DataList1" runat="server" onitemdatabound="DataList1_ItemDataBound">
<itemtemplate>
<asp:label id="lblTest" runat="server" text="Label"></asp:label>
</itemtemplate>
</asp:datalist>

WebUserControl CodeBehind
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace AtlasTest
{
public partialclass WebUserControl1 : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindData();
}
}

private void BindData()
{
List<string> testList =new List<string>();
testList.Add("One");
testList.Add("Two");
testList.Add("Three");
testList.Add("Four");
testList.Add("Five");

DataList1.DataSource = testList;
DataList1.DataBind();
}

protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
{
if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
{
string test = e.Item.DataItemas string;

Label lblTest = e.Item.FindControl("lblTest")as Label;

lblTest.Text = test;
}
}
}
}

It seems like there are some severe issues with Atlas and Caching. Is the Atlas team aware of this? If so is there a fix coming soon or a work around?

Thanks,

Joe


Hi,

is there any user control with cache enabled, in your page? What I suggest is, if you have user controls in your page, to remove each one and see if the problem persists. Specifically, look for controls or user controls that are *outside* an UpdatePanel.

Yeah, there was one usercontrol that used cache. It happens to be the only place where caching is used. I disabled the cache and have yet to encounter the exception. Is there a way to use both atlas and caching that I am not aware of? Is this behavior expected to be fixed in the final release. I will keep caching disabled for the time being as we cannot have random exceptions being thrown about,Big Smile but I would really like to use both.

Joe


Hi,

yes, there is an issue with the UpdatePanel and Output caching, at least in the April CTP:

http://forums.asp.net/thread/1318184.aspx

I don't know if it has been fixed in the current CTP (June), you can try to switch to the June CTP and see if it works, otherwise I'll do a test later. Let me know how it goes.

Thanks for the post about the issue, i have been looking everywhere (or so I thought) trying to find some more info.

I updated to the June CTP hoping that it was indeed fixed, but the same exception is still being thrown. I did not see error being fixed in the release notes as well, so I am assuming that it is not fixed. Hopefully it will be soon.Big Smile

Really appreciate the help and info.

Many Thanks,

Joe


I'm also encountering the same issue with the July CTP. I'm just hoping this will be fixed in whatever the next release is, as output caching is such a huge performance benefit.

Mark