Wednesday, March 28, 2012

Vertical Tabs?

Is there a way to have the AJAX tabs line up on the left hand side, instead of on the top?

There isn't a simple property to change arrangement, but you should be able to accomplish that through overriding all of the related CSS.

Vertical tabs

I posted on in the toolkit forum but thought I would widen the audience a bit.

What's the best method these days for creating vertical tabs? I currently use the toolkit's tab control for my horizontal tabs but I want to put it in another tabcontainer that has vertical tabs (kinda like an old style TV set with channels as buttons). How are people doing this these days? Doesn't look like the AJAX tab control can be made into vertical tabs and after googling around I didn't see anything that jumped out at me.

Thoughts?

Thanks!

Craig

Hello craigcl,

I didn't see the implementation of this, but consider reading this article
http://www.codeproject.com/aspnet/WebTabControl.asp?df=100&forumid=304531&exp=0&select=1758008
and downloading the AJAX Toolkit sources helps your to create your own vertical
tabs

c> I posted on in the toolkit forum but thought I would widen the
c> audience a bit.
c>
c> What's the best method these days for creating vertical tabs? I
c> currently use the toolkit's tab control for my horizontal tabs but I
c> want to put it in another tabcontainer that has vertical tabs (kinda
c> like an old style TV set with channels as buttons). How are people
c> doing this these days? Doesn't look like the AJAX tab control can be
c> made into vertical tabs and after googling around I didn't see
c> anything that jumped out at me.
c>
c> Thoughts?
c>
c> Thanks!
c>
c> Craig
c>

It doesn't do this out of the box, but you can customize the AJAX Control Toolkit's tab control to do this. If you look at the tab's source, you'll see it renders just simple SPANs and DIVs. You can get a bit more insight on what is happening if you look atmy blog post on styling the tabs.

Hope this helps.

-Damien

Vertical tabs

What's the best method these days for creating vertical tabs? I currently use the toolkit's tab control for my horizontal tabs but I want to put it in another tabcontainer that has vertical tabs (kinda like an old style TV set with channels as buttons). How are people doing this these days? Doesn't look like the AJAX tab control can be made into vertical tabs and after googling around I didn't see anything that jumped out at me.

Thoughts?

Thanks!

Craig

Hi Craig,

Currently, there isn't a easy way to customize the tab control to show tabs vertically. But I don't think is quite difficult to implement your own one.

1. You may place several buttons vertically on the page.

2. Add some panels with corresponding content in them

3. Add javascript to control the visibility of these panels within the client side click handler of buttons

very basic question about the atlas samples

I went thru the instructions exactly (well almost...the create new item for the webservice in VS2005 is incorrect in the tutorial, it should be Create new website)

http://atlas.asp.net/docs/Walkthroughs/GetStarted/Basic.aspx

But i keep getting aError: Samples is undefined

I tried this in an attempt to fix it..but it failed too (this URL i put in the Start URL in the webservice)..I wasnt sure

<atlas:servicereferencepath="http://localhost:1169/AtlasWebService/HelloWorldService.asmx"/>

What dumb thing am i missing?

Thanks!

What do you get when you go tohttp://localhost:1169/AtlasWebService/HelloWorldService.asmx/js

Executing:

http://localhost:1169/AtlasWebService/HelloWorldService.asmx/js

Gives:

Server Error in '/AtlasWebService' Application.


Request format is unrecognized for URL unexpectedly ending in '/js'.


That is why you are getting the 'undefined Samples' javascript error. Atlas will generate the javascript objects for your webservice if you have it configured correctly. Using /js after your webservice is a good way to test if this is working.

I would recommend taking the following steps to debug this issue:

1) Double check that you are using the April CTP of Atlas. You may want to uninstall your current version and re-install the version found by going to http://atlas.asp.net/ and clicking the 'Download' button.

2) When you create your website, make sure the template you select is called _"Atlas" Web Site_. This template will give you a web.config to start from that has the appropriate configuration settings to enable generation of javascript for your web service.

3) Follow the steps in the walkthrough to create the web service. Note that the instructions are correct. Make sure you right-click on the web project (not the solution) and select 'Add New Item'. Web Service will be one of the options.

4) Test your web service by setting it as the start page and pressing F5. You should get the standard web service test page - click on the web service and make sure it works. If it does, then add '/js' to the path and see if Atlas generates javascript.

5) Follow the steps in the walkthrough to create the test page.

My guess is that your problem is caused by a configuration error. By following the steps above, you should discover what was causing the problem.
Regards,
Kyle

I'm going to assume you are using one of the wallkthroughs like this one,"Walkthrough: Creating a Basic ASP.NET 'Atlas' Web Application"

I ran into this same problem you did and the fix went like this:

When i created the new "Atlas Website", i right clicked on the root and chose "Add New", then "WebService", and put "HelloWorldService.asmx"

This did two things:
- Created "HelloWorldService.asmx" in the root of the directory
- Created "HelloWorldServer.vb" in the App_Code directory

I had then copied and pasted the code right from the sample walkthrough into the VB file....

But here was the catch, and the cause of the problem:
- The sample has "Namespace Samples.Atlas" or something the like wrapped around its classes

- Well, back on the asmx, it had put:
<%@. WebService Language="VB" CodeBehind="~/App_Code/HelloWorldService.vb" Class="HelloWorldService" %>

- And since we had just changed the classes namespace since we copied and pasted from the code on the walkthrough, we broke the link between the two, hence the "Samples in undefined" error

So my fix was to change the asmx file to say

<%@. WebService Language="VB" CodeBehind="~/App_Code/HelloWorldService.vb" Class="Samples.Atlas.HelloWorldService" %>

Problem = solved


Thanks Kyle, it was my error that i didnt read the docs closely enough...i had passed by the right click on the atlas website, and created a asp.net webservice thru the right click new webservice on the solution.

I assume that i can do the latter, later, by manually copying the relevant config entries for Atlas into the non-Atlas asp.net web.config...

thanks again

Very Basic Static Method Question - SlideShowExtender

I'm working with the SlideShowExtender to show slides from a database. I have everything working as planned, except for a major oversight which I can't figure out how to get around properly. Internally I am housing a static SlideList object which contains all the slides returned from my DAL. Inside my

static AjaxControlTookit.Slide[] GetSlides() method I am copying the SlideList interal objects into the Slide[] object and then returning it. Now for my problem, naturally because my SlideList is static, there is only one copy across each page. When more than one user is on the website at the same time, obviously they are touching the same slideshow data which is causing a lot of problems. What is the correct way to handle this solution? Was I supposed to place the GetSlides() method in a WebService.asmx webservice, or is it ok to keep them as PageMethods and then correctly keep track of the Slides on a per page basis?

I would rather keep the GetSlides() method as a static PageMethod so I don't have to completely refactor the entire project, however I am not sure how I would correctly go about having Slides and then accessing them within my static methods. I realize this is a very elementary problem, and I feel awfully silly for not knowing the answer!

THanks!

Hi,

Your question is how to return different slides upon different requests, isn't it?

Well, you may pass a parameter (contextKey) into the GetSlides method, and use it to filter some slides.

For example, let's say you plan to filter the slides according to the userName of the one is browsing the page, you assign current user name in Page_Load.

protected void Page_Load(object sender, EventArgs e)
{
this.slideshowextend1.ContextKey = currentUserName;
}

[System.Web.Services.WebMethod]
[System.Web.Script.Services.ScriptMethod]
public static AjaxControlToolkit.Slide[] GetSlides(string contextKey)
{ // return a slide array according to contextKey
}

Hope this helps.

Very confused about state in my behavior-derived class

I am writing a very simple custom control extender as a first step towards building something slightly more complex. The intention of the extender at this point is just to make a panel visible in the onmouseover event of the target control. The code below is the javascript file that is registered with the control. What I'm finding is that the property I create called _panelId is set properly when the class is initialized (I can tell by the alert box I put in set method), but the property shows up as undefined when the handler for the onmouseover event fires (once again I tested this with an alert box). It's as though the class doesn't know its own properties when it gets to the _onMouseOver function.

My appologies if I'm missing something stupid, but I've been looking at this code all afternoon and can't figure it out...

Type.registerNamespace('Ballito');Ballito.HoverPanelBehavior = function(element) { Ballito.HoverPanelBehavior.initializeBase(this, [element]);// Propertiesthis._panelId =null;// Eventsthis._onmouseoverHandler =null;this._onmouseoutHandler =null;}Ballito.HoverPanelBehavior.prototype = { initialize : function() { Ballito.HoverPanelBehavior.callBaseMethod(this,'initialize');this._onmouseoverHandler = Function.createDelegate(this,this._onMouseOver);this._onmouseoutHandler = Function.createDelegate(this,this._onMouseOut); $addHandler(this.get_element(),'mouseover',this._onMouseOver); $addHandler(this.get_element(),'mouseout',this._onMouseOut);this.get_element().className =this._nohighlightCssClass; }, dispose : function() {if (this._onmouseoverHandler) { $removeHandler(this.get_element(),'mouseover',this._onmouseoverHandler);this._onmouseoverHandler =null; }if (this._onmouseoutHandler) { $removeHandler(this.get_element(),'mouseout',this._onmouseoutHandler);this._onmouseoutHandler =null; } Ballito.HoverPanelBehavior.callBaseMethod(this,'dispose'); }, _onMouseOver : function(e) { alert('_panelId = ' +this._panelId); var panel = Sys.UI.DomElement.getElementById(this._panelId);if (panel) { panel.Visible ="true"; } }, _onMouseOut : function(e) { var panel = Sys.UI.DomElement.getElementById(this._panelId);if (panel) { panel.Visible ="false"; } }, get_panelId : function() {return this._panelId; }, set_panelId : function(value) {if (this._panelId !=value) {this._panelId =value;this.raisePropertyChanged('panelId'); } alert(this._panelId); }}Ballito.HoverPanelBehavior.descriptor = { properties: [ {name:'panelId', type: String} ]}Ballito.HoverPanelBehavior.registerClass('Ballito.HoverPanelBehavior', Sys.UI.Behavior);Sys.Application.notifyScriptLoaded();

Hi,

the problem is that you are defining delegates but you're not attaching them as event handlers:

$addHandler(this.get_element(),'mouseover',this._onMouseOver);$addHandler(this.get_element(),'mouseout',this._onMouseOut);
becomes:
$addHandler(this.get_element(),'mouseover',this._onmouseoverHandler);$addHandler(this.get_element(),'mouseout',this._onmouseoutHandler);

Hi Garbin,

Thanks very much! That did take care of my state problem. Unfortunately (for me at least), it only got me one step further. Now I get the ID of the panel just fine in the mouse over event, but the call to getElementById() returns null. The documentation on this method is somewhat limited, but it seems to say that if I use the syntax I have in my code (not specifying the parent of the element), document is assumed. My assumption has been that this refers to the document that is referencing the script, i.e. the current page. Is this a valid assumption and regardless of that is this a valid way to grab an element off the page that uses my extender control? If not, is there a way to do that?

Just to make sure I'm clear, I want to set the _panelId property to the ID of a panel control on the page housing the extender control and then to get a reference to that panel using the ID in my mouse over script so I can change properties on it. Is this possible, and if so am I trying to do it the best way?

Thanks for your help,

Lee


Hi,

are you sure that the client id of the panel matches the id that you're passing to getElementById()?

Regarding the extender, I suppose that you want to get a reference to the corresponding behavior, right? If so, you should set the BehaviorID property on the extender and then use its value to get a reference to the behavior, together with the $find method:

var behavior = $find('behaviorID');


Hi Garbin,

Thanks for your response. To answer your question, yes, I am very certain the ID of the panel matches the ID being passed to the getElementById() method. I check the value passed with the alert box immediately preceding the call to getElementById() and it definitely does match the ID of the desired panel on the page where the extender control is defined.

Regarding the second part of your post, I'm not sure exactly where your going. Do I need a reference to the behavior in the script? I was thinking that once I got the reference to the panel from getElementById(), I'd be able to directly set its properties and that that's pretty much all it would take at this point. Is this wrong? Sorry if I'm missing something obvious, just trying to get started here.

Thanks,

Lee


Hi,

sorry, I didn't want to confuse you. If you need a reference to the DOM element (the panel) then getElementById (or $get, a shortcut to access the same method) is the way to go. At this point, since you're getting an error, could you post a simple example that reproduces the problem?


 Hi Garbin,
 Here's the source for a simple page that duplicates the problem:
First, the C# class that derives from ExtenderControl and defines my little "HoverPanel" control:
using System;using System.Data;using System.Configuration;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;using Microsoft.Web.UI;using System.Collections.Generic;namespace Ballito.CS{ [TargetControlType(typeof(Control))]public class HoverPanel : ExtenderControl {private string _panelId;public string PanelId {get {return _panelId; }set { _panelId =value; } }protected override void OnPreRender(EventArgs e) {base.OnPreRender(e);// Test for ScriptManager and register if it exists ScriptManager sm = Microsoft.Web.UI.ScriptManager.GetCurrent(Page);if (sm ==null)throw new HttpException("A ScriptManager control must exist on the current page."); sm.RegisterExtenderControl(this, FindControl(this.TargetControlID)); }protected override IEnumerable GetScriptReferences() { ScriptReference reference =new ScriptReference(); reference.Path = ResolveClientUrl("HoverPanel.js");return new ScriptReference[] { reference }; }protected override IEnumerable GetScriptDescriptors(Control targetControl) { ScriptBehaviorDescriptor descriptor =new ScriptBehaviorDescriptor("Ballito.HoverPanelBehavior", targetControl.ClientID); descriptor.AddProperty("panelId",this.PanelId);return new ScriptDescriptor[] { descriptor }; } }}

Next, the script file used by the control (largely the same one as in my original post):

// JScript FileType.registerNamespace('Ballito');Ballito.HoverPanelBehavior = function(element) { Ballito.HoverPanelBehavior.initializeBase(this, [element]);// Propertiesthis._panelId =null;// Eventsthis._onmouseoverHandler =null;this._onmouseoutHandler =null;}Ballito.HoverPanelBehavior.prototype = { initialize : function() { Ballito.HoverPanelBehavior.callBaseMethod(this,'initialize');this._onmouseoverHandler = Function.createDelegate(this,this._onMouseOver);this._onmouseoutHandler = Function.createDelegate(this,this._onMouseOut); $addHandler(this.get_element(),'mouseover',this._onmouseoverHandler); $addHandler(this.get_element(),'mouseout',this._onmouseoutHandler); }, dispose : function() {if (this._onmouseoverHandler) { $removeHandler(this.get_element(),'mouseover',this._onmouseoverHandler);this._onmouseoverHandler =null; }if (this._onmouseoutHandler) { $removeHandler(this.get_element(),'mouseout',this._onmouseoutHandler);this._onmouseoutHandler =null; } Ballito.HoverPanelBehavior.callBaseMethod(this,'dispose'); }, _onMouseOver : function(e) { alert(this._panelId); var panel = Sys.UI.DomElement.getElementById(this._panelId); alert(panel);if (panel) { panel.Visible ="true"; } }, _onMouseOut : function(e) { var panel = Sys.UI.DomElement.getElementById(this._panelId);if (panel) { panel.Visible ="false"; } }, get_panelId : function() {return this._panelId; }, set_panelId : function(value) {if (this._panelId !=value) {this._panelId =value;this.raisePropertyChanged('panelId'); } }}Ballito.HoverPanelBehavior.descriptor = { properties: [ {name:'panelId', type: String} ]}Ballito.HoverPanelBehavior.registerClass('Ballito.HoverPanelBehavior', Sys.UI.Behavior);Sys.Application.notifyScriptLoaded();

Finally, the markup for a simple page that uses the control:

<%@. Page Language="C#" %><%@. Register Namespace="Ballito.CS" TagPrefix="ballito" %><!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 id="Head1" runat="server"> <title>ASP.NET AJAX Behavior Sample</title></head><body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <div> <asp:Panel ID="Panel1" runat="server" BackColor="Cyan" Height="50px" Width="125px" Visible="False"> </asp:Panel> <asp:Button runat="server" ID="SampleButton" Text="Submit Form" /> <ballito:HoverPanel ID="hoverPanel1" runat="server" TargetControlID="SampleButton" PanelId="Panel1" /> </div> </form></body></html>

The behavior I find is that when I run the page and mouse over the button, I can tell the onmouseover event in my control does fire since the alert box in it is displayed. This is the alert box right before the call to getElementById(). As I said in the last post, the alert box shows the value of the _panelId property properly ("Panel1" in this case). The problem is that the alert box that fires right after the getElementById() call shows that the value returned by getElementById() is null instead of [object].

Thanks for the help,

Lee


Hi,

you are setting the Visible attribute of the Panel to false. This means that the Panel won't be rendered on the page and this is the reason why you are getting a null reference.

If you want to hide the panel, you could style the Panel using display:none or visibility:hidden


Hi Garbin,

Well this finally got me going down the road. I'm finding there is still a lot for me to figure out, but I'm starting to get things to work in some sort of expected manner and that's usually what it takes for me to get movement when learning something new. Thanks for all your help.

Lee

Very long loading times on II7 free hosting sites

I've deployed a recently started project on 2 IIS 7 free hosting companies, hostmysite.com and maximumasp.com.

I have encountered big loading times on the whole site, but mostly at AJAX parts. For example I have a few cascade drop down lists and it takes 2-3 seconds to populate 1 dropdown with 3-4 listitems when the user selects something in the first dropdown. On my localhost it happends faster than you blink (E6660, 2 GB RAM).

Have anyone tried out this services ? Its their fault for the big loading times or maybe it's something from my code ? I'm really worried about this and I have no other testing option except this free hosts.?

Well, how does it run for you in development?

You really need to look at what's slow. Is it your app or is the Internet Connection? Is it latency (ie. startup of the app) or is it request times that are slow.

Hosting sites often have issues with very short Application Pool timeouts that cause the entire app to shut down and are then slow to restart. However, this should not be an issue if you use the site for a number of hits in a row.

+++ Rick --


I'd recommend you first use something like FireBug (or the IE equivalent) to monitor the network traffic your partial postbacks cause. It sounds like the network traffic is your bottleneck. Especially watch out for huge ViewStates that get uploaded with every partial postback.


On developing machine it's instant.

I used firebug to do some texts on a page. I have 2 dropdown lists in an update panel and below (outside the update panel) I have a huge gridview. The problem seems to be that gridview's huge viewstate that gets uploaded/downloaded with every partial postback asgt1329asaid.

Now I know the problem. But whats the solution ? Why does the gridview's view state gets uploaded/downloaded everytime even if the gridview is not inside the update panel ?


Unfortunately, the full page's ViewState is sent back and forth on any partial postback. There's no way around that. Though, most of the time there are controls that you can disable ViewState on to minimize it. Or, if you're doing a lot of postbacks, you might consider rebinding controls on the server side, instead of using ViewState to persist them (viability of this really depends on how your page works).

The other option is that you can use web methods/services to replace some of your heavily used UpdatePanels with JSON communication:

http://ajax.asp.net/docs/tutorials/ASPNETAJAXWebServicesTutorials.aspx


Thanks for all the possibilities you recommended me.

Knowing almost nothing about them all I would also like a suggestion about what method to use. I'm trying to make minimize partial postbacks times because 3 seconds for populating a dropdown list with 5 items it not an acceptable time at all.

Using Web Services seems to most suitable method, but as I said, I know almost nothing about them all so I would like to hear an opinion from someone who knows more than me.


You should attempt to do both. Optimize your ViewState and replace partial postbacks with leaner alternatives when it's possible.

Most controls that are based on form elements can have ViewState eliminated. This is beneficial, even in non-AJAX scenarios, but will especially help cut down on the network footprint of your partial postbacks.

Web Method/Services are great. However, you can't (realistically) use them for anything that needs to modify ViewState. I'd say they're especially well suited to read-only operations that display changing data. A stock ticker, for example. On the other hand, manipulating a GridView with Web Methods would be tough. For more info on web methods vs. UpdatePanels, take a look at this:http://encosia.com/index.php/2007/07/11/why-aspnet-ajax-updatepanels-are-dangerous/

Also, don't forget the AjaxToolkit. For your dropdown, you could use the cascading dropdown extender in the toolkit to do half the work for you (just need to make the web service for it and you're done).


Allright I've used cascadeDropDown extender for my 2 dropdowns and wrote a WS to handle them. The problem is now that depending of the selection I make in the first dropdown I also want to display or hide a label or change it's Text value. This cannot be done within the WS so I'm back to where I started.


I believe those dropdown extenders fire the normal client side events. So, you could handle EndRequest() to change cosmetics like a text label or div visibility on the client side (or do it on BeginRequest, if you wanted).

Basically, if it's a read-only, cosmetic change, try to do it in client script if you can.


If you are looking for super lightweight grid which support binding data from a web service call try thishttp://dotnetslackers.com/articles/ajax/ASPNETAjaxGridAndPager.aspx


Could you please detail this gt1329a ?

VERY new to asp.net AJAX: Enabling controls based on slection from AutoComplete control

I've been reading all day and I'm not finding the solution to my requirement.

I'm developing a form to enter "lead" information, part of the lead data is the name of their Dr. We maintain a MySql DB with leads and Drs information.

When a user is entering a new lead and they type the last name of the Dr I have a AutoCompleteExtension fetching Dr.s that match the last name. When/if the user selects a Dr. from the list I want to DISABLE the other Dr. related fields (FName, address, etc) and insert the data from the selected Dr. If there is no match found, the user will enter the details for the Dr. (new record).

The main issue I'm struggling with is how to respond (client or server) to the user making a selection from the AutoComplete list and enable/disable and populate the related fields. For example, the user picks a Dr. from the list, I then want to disable all the Dr. detail related fields and set the values with the record from the database.

I'm not sure how I will accomplish this yet, I imagine I would need to set those values from the server side and it would in turn use AJAX to push the values down to the client?

If anyone could give me a little guidance I would really appreciate it, I just need a jump start to get this thing going.

Thanks for reading,
Steve


If you're Textbox that has the AutoComplete extention on it loses focus, why not use the onBlur event to check to see if they used your AutoComplete (which would have text in that textbox). If they did use the AutoComplete, then use JavaScript to disable the other textboxes.


You could use the ItemSelected event of the AutoComplete extender in the client and as RTernier says use JavaScript to disable the other textboxes, you could call a webservice to obtain the remaining information of the doctor, check: http://www.asp.net/ajax/documentation/live/tutorials/ExposingWebServicesToAJAXTutorial.aspx
http://www.asp.net/ajax/documentation/live/tutorials/EmbedScriptFile.aspx For information on using WebServices. You could also use an UpdatePanel, I guess you could call a partial post back from the ItemSelected event, although I'm not an expert in UpdatePanel, but I think it would work (personally I like the webservice way better, but it's a matter of choice).

Very new to AJAX. Want to insert a record into a database...

Hello everyone,

I am very new to ASP.NET AJAX. I just simply want to insert a new record into a database...

I have a calender, which is using DayRender to highlight days that have meetings on them (pulled from "Meeting" table in database).

When a user selects a date that DOESN'T have a meeting, i want an "Add" button to show that will simply add the calendar's selected date to the Meeting table (the table only has two fields, ID and Date)

I'd like for this to all be AJAXified, so when a user selects a date...it does a partial page render to show the add button (or delete button if there IS a meeting for the selected date already), then when they click the "add" button, it inserts the selected date with a partial page render (or however it works).

Can anyone point me in the right direction? Do I have to create a web service? can i do this just using UpdatePanels? Can someone possibly provide some starter code?

Thanks in advance!

hello.

well, since you're starting, i'd say that this can be done by rather easily with UpdatePanels. Even though i still think they shouldn't be used in most scenarios, the truth is that ~using them makes building ASP.NET AJAX pages easy since you can do most of things on the server side...

Very rich data to be presented in pushpin popup - how to?

Hello,

suppose we have a list of objects retrieved from a webservice which we want to present in Virtual Earth Map as a set of pushpins. And one of fields of the object (presented in one pushpin) is another list. For example consider object of the following class:

1public class Point2{3string city;4string lat;5string lon;6 List<Person> list;7}
 wherePerson is another class like:
 1public class Person2{3string firstname;4string lastname;5string about;6}  

Now, I need to make a pushpin from every Point object of the list retrieved from the webservice. That's the easy part. :)

My problem is how to present the list of - let say - lastnames from List<Person> list in pushpin popup. Any ideas how to do it in a declarative way?

I'm still using the Atlas, not ASP.NET AJAX.

Please! Any help! I'm so confused :)

Hi,

check the mashup in my signature, it performs something similar, but with a list of images. You can download the source code.


Wow. This is a very nice application. :)I'm studying it hard.

Maybe you know some good sources of information about xml-script?


Just wondering, is your demo updated for the Beta release?

Hi,

no, at the moment it works only with the July CTP.


So, any clues where to find information about programming Atlas in a declarative way (by XML-script)?

Your demo is excellent example, but still example and I would love to learn all of it :) The old Atlas documentation is not available. Maybe someone has it?

Very simple example... with masterpage!

I create a really simple example using atlas on a masterpage.

Ihave this code:

<

cc1:ScriptManagerID="ScriptManager1"runat="server"EnablePartialRendering="true"></cc1:ScriptManager><cc1:UpdatePanelID="up2"runat="server"><ContentTemplate><asp:Labelid="lbl1"runat="server"Text="Label"></asp:Label><BR/><asp:LinkButtonid="LinkButton1"runat="server"OnClick="LinkButton1_Click">LinkButton</asp:LinkButton></ContentTemplate>

</cc1:UpdatePanel>

and this:

protectedvoid LinkButton1_Click(object sender,EventArgs e)

{

lbl1.Text =

"egege";

}

the problem is that the event is raised, lbl1.Text became "egege", but the text of the label on the page it is still the same...

what can be wrong?

Can you supply a bit more code and perhaps explain how the cc1 namespace prefix got placed in front of your atlas controls?

<cc1:ScriptManager......

Instead of

<atlas:ScriptManager....

Etc.

I'm not saying that's the problem, but I'm unfamiliar with how that prefix got there.


hello.

btw, you should also start by using fiddler to see the msg that the client is receiving from the server...is there any forbidden xml chars on the head section?


Eureka!

The problem was that there was a<script language="Javascript"> block on the head of my masterpage.

I canceled it and everythigs works!

Can anybody tell me why?


hello.

well, currently, atlas packages the content of the head element in the msg that is sent from the server in response to a partial postback. since it doesn't escape those elements (say, by using a cdata section), you can't have any forbidden xml chars there (and it's really easy to get one of those inside a javascript script - for instance, this would make your document not well formed: for( ; i < 10; i++ ))

in the current version of atlas, when the returned xml document isn't well formed, the client platform discards it without giving any feedback.

Very slow and unresponsive AJAX (Calendar + Tabs)

i just installed the toolkit into Visual Studio 2005, and managed to create some sample projects

I've implemented the Tabs and Calendar onto an existing project, in the believe that Ajax would provide faster (or as fast) access then the existing solution.

in order to make the Ajax work in the project, I've copied nearly all needed elements into the web.config ( http://codebetter.com/blogs/jay.kimble/archive/2006/10/26/How-To_3A00_-Enable-Microsoft-Ajax-Beta-over-on-an-existing-site.aspx )

now - the Ajax Calendar and Tabs works, the old server side asp.net have been fitted to the new controls...

but very very slow !?!? - the calendar takes 3-4 seconds to show and a single action in it takes 1-2 seconds ?

code:

1<%@dotnet.itags.org. Control Language='vb' AutoEventWireup='false' Codebehind='ctlQuizEdit.ascx.vb'2 Inherits='SurveyFactory.ctlQuizEdit' TargetSchema='http://schemas.microsoft.com/intellisense/ie3-2nav3-0' %>3<%@dotnet.itags.org. Register TagPrefix='fcke' TagName='FckHeader' src='ctlImportDefLangHeader.ascx' %>4<%@dotnet.itags.org. Register TagPrefix='fcke' TagName='FckFooter' src='ctlImportDefLangFooter.ascx' %>5<%@dotnet.itags.org. Register TagPrefix='cc1' TagName='HeaderFooter' src='ctlHeaderFooter.ascx' %>6<%@dotnet.itags.org. Register TagPrefix="cc1" Namespace="AjaxControlToolkit" Assembly="AjaxControlToolkit" %>789<cc1:TabContainer Height="250px" Width="600px" ID="TabContainer1" runat="server">10 <cc1:TabPanel ID="TabPanel1" runat="server" HeaderText="Survey">11 <ContentTemplate>12 <table id="editQuizData" runat="server" width="100%" cellspacing="1" cellpadding="2" border="0" height="10">13 <tr>14 <td align="left" colspan="2">15 <asp:Label ID="lblQuizAction" Text="Edit" Font-Bold="True" runat="server" /><br>16 <asp:Label ID="lblError" runat="server" />17 </td>18 </tr>19 <tr>20 <td align="left">Title</td>21 <td align="left"><asp:TextBox ID="txtQuizTitle" Columns="80" runat="server"></asp:TextBox></td>22 </tr>23 <tr>24 <td align="left">Description</td>25 <td align="left"><asp:TextBox ID="txtQuizDescription" Columns="80" Rows="2" TextMode="MultiLine" runat="server"></asp:TextBox>26 </td>27 </tr>28 <tr>29 <td align="left">Created by</td>30 <td align="left"><asp:Label ID="lblCreatedBy" runat="server" />31 </td>32 </tr>33 <tr>34 <td align="left" valign="top">Interval</td>35 <td align="left">36 <table id="Table1" runat="server" width="100%" cellpadding="0" cellspacing="0" border="0">37 <tr>38 <td align="left" valign="top">From</td>39 <td align="left" valign="top">To</td>40 </tr>41 <tr>42 <td align="left">43 <asp:TextBox ID="CalendarQuizFrom" runat="server"></asp:TextBox>44 <cc1:CalendarExtender ID="CalendarExtender1" runat="server"45 TargetControlID="CalendarQuizFrom" Format="dd-MM-yyyy" />46 </td>47 <td align="left">48 <asp:TextBox ID="CalendarQuizTo" runat="server"></asp:TextBox>49 <cc1:CalendarExtender ID="CalendarExtender2" runat="server"50 TargetControlID="CalendarQuizTo" Format="dd-MM-yyyy" />51 </td>52 </tr>53 </table>54 </td>55 </tr>56 </table>57 </ContentTemplate>58 </cc1:TabPanel>59 <cc1:TabPanel ID="TabPanel2" runat="server" HeaderText="Header">60 <ContentTemplate>61 <fcke:FckHeader runat="server" ID="FckHeader" />62 </ContentTemplate>63 </cc1:TabPanel>64 <cc1:TabPanel ID="TabPanel3" runat="server" HeaderText="Footer">65 <ContentTemplate>66 <fcke:FckFooter runat="server" ID="FckFooter" />67 </ContentTemplate>68 </cc1:TabPanel>69</cc1:TabContainer>7071<center>72 <asp:Button ID="btnSave" runat="server" Text="Save"></asp:Button> 73 <asp:Button ID="btnCancel" runat="server" Text="Cancel"></asp:Button>74</center>7576<input id="hiddenLangHeaderTxt" type="hidden" name="hiddenLangHeaderTxt">77<input id="hiddenLangFooterTxt" type="hidden" name="hiddenLangFooterTxt">78<input id="hiddenFooter" type="hidden" name="hiddenFooter" runat="server">79<input id="hiddenHeader" type="hidden" name="hiddenHeader" runat="server">80

Hi Montago,

Your program works pretty well after I removed all the UserControls. So we suggest that you should use an exclusive method that remove the controls one by one until find out the exact root cause. Also, Some helpful debugging tools will make your work easy. For example,IE WebDevelopment Helper,HttpWatch,Firebug etc.

If your problem cannot be resolved , please let me know with more information.

Best regards,

Joanthan

Very slow dragndrop in IE using DragDropManager

There are 2 realizations of DragDropManager in Ajax Controls:IEDragDropManager &GenericDragDropManager.

GenericDragDropManager works fine. But IEDragDropManager works slow, very slow. If I forcedly use the GenericDragDropManager for IE browser every works fast. It's clear that IEDragDropManager has some realization issues.

What's the problem and when it will be fixed?

Could be because you're running in debug mode... if so one of these:

1) Set<configuration><system.web><compilationdebug="false">in your web.config

2) Set theScriptMode="Release"property on the ScriptManager component

<asp:ScriptManagerID="ScriptManager1"runat="server"ScriptMode="Release"></asp:ScriptManager>

Either way, you should end up with the release version of the javascript coming down to you which is A LOT faster!!


Yeah, it's helped a little. But the draggins is still too slow and not acceptable for real world.

The problem isn't solved.

very very simple question about $get

in javascript how can I transform this :

var texte=document.getElementById("Text1").value;

with a $get ? I've tried var texte=$get("Text1","value"); but it doesn't work ?

I'm on Vista with VS 2008 RTM

Thanks

Try var texte=$get("Text1").value, basically $get() is a shortcut to document.getElementById()

Hope this helps,

Elias.


thanks it works, I was waiting for intellisense, but $get(tytu). there is no intellisense.


Keep in mind that $get is exactly the same as getElementById. They both return a reference to the supplied DOM element. $get is just a shortcut, to save typing and improve readability.

If you have existing code using getElementById, you don't have to convert it to $get unless you want to.

very weird problem

I have installed lastest ajax and also toolkit too. I created master page and default aspx page, then I put my scriptmanager inside the master page and update panel inside the default page, I didn't choose ajax enable website because I have a hard time to place my existing web.config files, assemblies, connection strings to right place of the enable ajax's web.config file. Maybe I should though, with this error.

I get errors sometimes with all the controls in update panel, is not recognized my html tag, even though my controls are declared, it says it is not, But it builds application suscessfully. I made sure I put this

<%@dotnet.itags.org.RegisterAssembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"Namespace="System.Web.UI"TagPrefix="asp" %>

to my page and also in web.config file under config section also assemblies too. Thing is I think every time I backup my website to my documents, for some reason a while later this happens. I even reset my iis to clear my temp folder of asp.net too. Still. Why this is happening ?

You'll also need an reference to the following assemblies:

- AjaxToolKit.dll
- System.Web.Extensions.dll

You can do this using right click on your project, "Add Reference" and point to this DLL's


On bin folder, I have got these ar, cs, de, es, fr,he,hi,it,ja,ko,nl,pt, ru,tr-TR,zh-CHS, zh_CHT all
thas AjaxControlToolkit.resources.dll in it.
Then AJaxCotrolKit.dll under neat AjaxControlKit.dll.refresh and AjaxControlKit.pdb

Microsoft.Web.UI.WebControls.dll with Microsoft.Web.UI.WebControls.dll.refresh


I have these dll on my bin now, and still problem


I had these dll on program file but not pointing to my project. I am right clicking my project and add references, choosing these dll and adding but it is not showing under my bin folder for some reason, can someone tell me steps to how to add these dlls to my projects.


Is anybody didn't have this problem? I go crazy here with this..


this was nothing to do with ajax, it was copy paste problem..

Very weird error. Ajax controls call default.aspx

I have a few pages in my site... and for some reason, if there's any ajax controls on the page, it calls default.aspx and runs the code every time any aspx page with an ajax control exists on it. Problem is, default.aspx resets my session variables.

Why does Ajax call the default.aspx page code? It only runs the CS file... it doesn't actually show the default.aspx page.

I doubt it calls it. Do you have a component in your site somewhere that's got a url of "/" attached to it somewhere, and that's invoking the default page?


it only seemed to only happen when I have Certain Ajax controls on the page. Note, it only does it with Internet Explorer 6 and 7. Firefox seems to be fine.

For example, I have a collapsible PAnel in each row of a Gridview. That is in an UpdatePanel. When the Gridview is populated (and I have a breakpoint on the default.aspx.cs file), it goes through that code. Well, I set my session variables on that page, so in essence it resets them.

It seems like it does this AFTER the page is loaded, because the labels that show content based on those session variables aren't updated until I go to a new page.

It only does this when I have a collapsible panel in IE. The panel is set to collapsed.


Actually, it appears that AJAX is clearing the Session Variables. I don't know where it's doing this, though.

Very Weird Problem with Cascading DropDown

After some version updates both in AJAX.NET and Control Toolkit, I found the Cascading DropDown does not work in my project. The appearance is: the DropDown is simply blank. Even the PromptText is not shown up in the page. DropDown is not populated while the web service is working fine. No error reports to me.

But at mean time, the Sample project of Cascading DropDown page works fine on the same machine.

If I copy my code into the Sample Project, it works. This means the code is correct. And web service is always OK if open asmx page and test it.

My project was created by selecting template of AJAX Enabled website, and then copy the AjaxControlToolkit.dll from Toolkit Sample project Bin folder to my project Bin folder. And then add reference to it. Very standard way.

I compared the difference of the sample project and my project, basically the reference. The only difference is that, the AjaxControlToolkit.dll in my project is versioned as "Auto Update", while in sample project it's versioned as 1.0.61121.0. BUT I DON"T KNOW HOW TO CREATE A PROJECT WITH REFERENCE OF THIS FILE TO BE VERSIONED AS 1.0.61121.0.

For your info, my code is mainly posted as following:

<!-- for aspx code: -->

<asp:DropDownList ID="DropDownList1" runat="server" Width="200px"></asp:DropDownList>
<ajaxToolkit:CascadingDropDown ID="CascadingDropDown1" runat="server" TargetControlID="DropDownList1" Category="Carrier" PromptText="Please select a carrier" LoadingText="[Loading carriers...]" ServicePath="uscarrier.asmx" ServiceMethod="ReturnUSCarriers"></ajaxToolkit:CascadingDropDown>

// webservice code
[WebMethod]
[Microsoft.Web.Script.Services.ScriptMethod()]
public CascadingDropDownNameValue[] ReturnUSCarriers(string knownCategoryValues, string category)
{
SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["CMSConnectionString_Prod"].ConnectionString);
SqlCommand cmd = cnn.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "select distinct Name, OperatorID from [CMS_Carriers] where OperatorID like '3%' and IsActive = 1";
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
DataSet ds = new DataSet();
da.Fill(ds, "Carriers");

List<CascadingDropDownNameValue> carriervalues = new List<CascadingDropDownNameValue>();

for (int i = 0; i < ds.Tables["Carriers"].Rows.Count; i++)
{
DataRow dr = ds.Tables["Carriers"].Rows[i];
carriervalues.Add(new CascadingDropDownNameValue((string)dr["Name"], dr["MBloxOperatorID"].ToString()));
}
return carriervalues.ToArray();
}

The ReturnUSCarriers method needs to be static. (This is covered in the ASP.NET AJAX migration docs as well ashttp://blogs.msdn.com/sburke/archive/2006/10/21/hint-components-that-use-web-services-with-asp-net-ajax-v1-0-beta.aspx.)

David:

Thanks for your reply. I set the method to be static, and it still does not work.


If this is a page method (looks like it is), then you may want to try removing the ServicePath property entirely.
my cascading dropdowns are no longer working as well. I am calling an external web service with the same method signiture as above.
also, this was after I upgraded to the RC and updated control kit.

figured it out, for some reason I was missing this in my web.config:

<addverb="GET,HEAD"path="ScriptResource.axd"type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"validate="false"/>


Shoot, I just realized those were needed for the Ajax to work in IE. And by me removing those lines from the web.config it just does a normal postback and not an asynchronous call. That is why it worked for me. So really nothing has changed. I am back to nothing on why the response.redirect() doesn't work. You guys mentioned that you took the code and were able to get the response.redirect() to work. I'm not sure what in my environment could be any different. I'm running this off of localhost and I do not have IIS running.

video in asp.net ajax like youtube

how to play videos in asp.net ajax like youtube.

You should check the Silverlight controls in the futures:

http://www.asp.net/downloads/futures/

Hope this helps,

Elias.

view images through xml

I am trying to create a slideshow that has some text and an image. I am able to scroll through the xml file and display the text elements. My problem is with the images. Can anyone help? Thanks

XML:

<?xml version="1.0" encoding="iso-8859-1" ?>
<dogs>
<info>
<name>Archer</name>
<handler>P.O. 1</handler>
<skills>Drugs</skills>
<birthday>4</birthday>
<imagesrc>Images/K9/Dogs/Archer.jpg</imagesrc>
</info>

code:

<xml src="http://pics.10026.com/?src=XML/dogs.xml" id="xmldso" async="false"></xml>

<table width="100%">
<tr>
<td style="width:50%;" align="right">
<span datasrc="#xmldso" datafld="imagesrc"></span>
</td>
<td style="width:50%;" align="left">
<table style="border: activeborder 1px solid">
<tr><td class="TableBottom" width="70">Name:</td><td class="TableBottom" width="100"><span datasrc="#xmldso" datafld="name"></span></td></tr>
<tr><td class="TableBottom" width="70">Handler:</td><td class="TableBottom" width="100"><span datasrc="#xmldso" datafld="handler"></span></td></tr>
<tr><td class="TableBottom" width="70">Skills:</td><td class="TableBottom" width="100"><span datasrc="#xmldso" datafld="skills"></span></td></tr>
<tr><td class="TableBottom" width="70">Birthday:</td><td class="TableBottom" width="100"><span datasrc="#xmldso" datafld="birthday"></span></td></tr>
<tr><td width="70"></td><td width="100"></td></tr>
</table>
</td>
</tr>
<tr>
<td align="center" colspan="2">
<A href="http://links.10026.com/?link=JavaScript:moveprevious()"> Back</A>
|
<A href="http://links.10026.com/?link=JavaScript:movenext()"> Next</A>
</td>
</tr>
<tr>
<td align="center" colspan="2">
<INPUT TYPE="text" WIDTH="100" NAME="Number" style="border:0; text-align:center;">
</td>
</tr>
</table>

<SCRIPT LANGUAGE="JavaScript">

function Start()
{
x=xmldso.recordset;
document.Canine.Number.value=x.absoluteposition+" of "+x.recordcount;
// document.getElementById("mypic").src =x.recordset("imagesrc") ;
}

function movenext()
{
x=xmldso.recordset;

if (x.absoluteposition < x.recordcount)
{x.movenext();}
else if (x.absoluteposition = x.recordcount)
{x.movefirst();}

document.Canine.Number.value=eval(x.absoluteposition);
document.Canine.Number.value=x.absoluteposition+" of "+x.recordcount;
}

function moveprevious()
{
x=xmldso.recordset;

if (x.absoluteposition > 1)
{x.moveprevious();}
else if (x.absoluteposition = 1)
{x.movelast();}

document.Canine.Number.value=eval(x.absoluteposition);
document.Canine.Number.value=x.absoluteposition+" of "+x.recordcount;
}

</SCRIPT>

Change this line <span datasrc="#xmldso" datafld="imagesrc"></span>

to <img datasrc="#xmldso" datafld="imagesrc" />

use the img html control instead of the span control. I tested this in my local machine and works fine

let us know

I tired that and did not work. When I scroll through the images, all I get the the missing image with the red x where the image should be.


Well, it should work. do you have the following image?

Images/K9/Dogs/Archer.jpg

right click the red icon and see the image path.


Yes, I have the image. I even moved it to the same folder as the xml file in case the path was not accurate.


Chris,

I am using IE 7 and it works fine. Which browser and what version are you using?


Forget my last comment. It did work. I did not properly refresh the xml file. Thanks for your help. It is appreciated.

View PDF in ATLAS?

In my existing 1.1 app, I have a datagrid with a column that, when clicked, displays a pdf file. In trying to convert it to 2.0 with Atlas, the pdf will not display, no error, but no display either. The data for the pdf is stored in SQL as binary data. I have listed the code below. If anyone could shed some light onto the issue, I'd greatly appreciate it.

If dr.Read Then
Dim byData(dr.GetBytes(0, 0, Nothing, 0, Integer.MaxValue) - 1) As Byte
dr.GetBytes(0, 0, byData, 0, byData.Length)
Response.ClearContent()
Response.ClearHeaders()
Response.Buffer = True
Response.AddHeader("Content-Disposition", "inline;filename=" & strFileName)
Response.AddHeader("Accept-Header", byData.Length)
Response.ContentType = strContentType
Response.BinaryWrite(byData)
Response.Flush()
Response.Close()
End If

Again, any feedback would be appreciated.

Thanks.

I ended up diong the postback in a different page.

What you will need to do is have a link in your datagrid to another page (ie viewattachment.aspx?filename=filename) and then create a non ajax windows form page called viewattachment.aspx

In the viewattachment.aspx page_load method you can then place your response code as you mentioned above

I have written an example of thishere.
Clinton

view problem within cc1:ModalPopupExtender ..

I have a view problem within cc1:ModalPopupExtender .. when I click an asp image button the specified panel located most top-left in a page even I do not use x or y ModalPopupExtender properties

this problem happens only with ie

in firefox everything works fine ..

here is ModalPopupExtender code :

<cc1:ModalPopupExtender ID="ModalPopupExtender3" runat="server"
TargetControlID="submitBuyImgBt"
PopupControlID="Panel1"
BackgroundCssClass="modalBackground"
DropShadow="true"
OkControlID="OkButton"
OnOkScript="onOk()"
CancelControlID="CancelButton" />

any help would be greatly appreciated

why it's position always in top left side of the page ?


what does the css look like for the panel? are you using one?

heres what i always use and it shows up at the center of the screen.

<ajax:ModalPopupExtender ID="mpeEditUserForm" runat="server" TargetControlID="btnEditUser" BackgroundCssClass="modalBackground"
PopupControlID="pnlUserModal" />
<asp:Panel ID="pnlUserModal" runat="server" CssClass="modalPopup" Style="display:none; padding:3px 3px 3px 3px" Width="320px">

css:

.modalBackground
{
background-color:Gray;
filter: alpha(opacity=70);
}
.modalPopup{
background-color:White;
border: solid 3px Gray;
padding: 3px 3px 3px 3px;

font-size:medium;
}


Mezzaluna:

what does the css look like for the panel? are you using one?

heres what i always use and it shows up at the center of the screen.

<ajax:ModalPopupExtender ID="mpeEditUserForm" runat="server" TargetControlID="btnEditUser" BackgroundCssClass="modalBackground"
PopupControlID="pnlUserModal" />
<asp:Panel ID="pnlUserModal" runat="server" CssClass="modalPopup" Style="display:none; padding:3px 3px 3px 3px" Width="320px">

css:

.modalBackground
{
background-color:Gray;
filter: alpha(opacity=70);
}
.modalPopup{
background-color:White;
border: solid 3px Gray;
padding: 3px 3px 3px 3px;

font-size:medium;
}

I have CSS but it's still not working .. but both panel and moalPopupExtender located in a web user control ( .ascx )

does the problem because of this ?

Note that every thing works fine in firefox. however not fine in ie6 or above


Not sure on that then. I always have the opposite problem. I get things to work in IE and they fail in Firefox.


Viewing Source - Javascript error on missing elements

Hello,

I know this is very likely to be my misunderstanding of how ajax works, but any help would be greatly appreciated.

When my page first loads there is a panel that is not visible, inside the UpdatePanel. After a partial postback this panel becomes visible, but when I 'View Source', the outputted code for the panel does not exists, nor the code for its child controls (even though they show on screen). This means when I try to use client-side code for a control in that panel, eg.

var t = window.document.getElementByID(childID);

it cannot be found as the childID doesn't appear in the source.

Any ideas?

Thanks very much.

Simon

This is actually expected... View/Source in the browser only displays the source that was sent down with the original request.

As for your specific issue, make sure you're using the client ID... a common idiom is: $get('<%= MyControl.ClientID %>'). $get() is a shortcut in ASP.NET AJAX for document.getElementByID().

viewing the script source

Previously, the script source was in a ScriptLibrary directory in a web
application. I want to view the source now with the March CTP. Is there a
way to view the source in the clientside javascript now?

Wally

--
Wallace B. McClure
"The Harder I Work, the Luckier I Get."
Listen to "The ASP.NET Podcast" at http://www.aspnetpodcast.com/
Database Award: http://url123.com/vc3er
Microsoft MVP - Visual Developer ASP/ASP.NET
AspInsider
"AJAX for ASP.NET" Coming Soon!
ADO.NET Book: http://url123.com/vc2bu
865-693-3004
118 Durwood Rd.
Knoxville, TN 37922
http://www.scalabledevelopment.com/
Blog: http://weblogs.asp.net/wallym/

Wally, the atlas scripts as now packaged as resources in the atlas dll. The Atlas MSI setup also installs them in the c:\Program Files\Microsoft ASP.NET\Atlas\v2.0.50727\Atlas\ScriptLibrary\Debug\ directory for you to view.

enjoy
-jhawk

ViewState

Hi,

Is there any way to turn off ViewState (for real) using the ScriptManager and UpdatePanel? I have EnableViewState on both set to false, but Im still seeing responses of about 100k.

Thanks

Joe

set the enableviewstate=false.

then use ctl+F5 for clear the cached output


Tried that, but it didnt make a difference (unless you are talking about at the page level, in which case I cant without fairly significant changes to things unrelated to what Im working on)

Thanks,
Joe


The EnableViewState property of the ScriptManager only refers to the ViewState of the particular ScriptManager control itself.

Due to the underlying way that UpdatePanels work, the full page's ViewState must be sent to the server. The full page life cycle is still executed in a partial postback, so the ViewState is necessary to re-instantiate the state of the page and it's controls.

However, you canuse page methods to avoid the data-heavy partial postbacks in many cases. The best solution really depends on what exactly you're trying to do, but there's unfortunately no way to remove the ViewState from partial postbacks.

Viewstate - Controls that are there but not there at the same time

Hi All,

I wonder if someone can help. I have just started using ajax and am converting an established application. It uses dynamically created controls to enter parameters for crystal. I have now got a panel that l holds the crystal component, and with testing of directly fed parameters this works fine. As soon as i try and use my dynamic componenets it can't see them. I have gathered this has got something to do with viewstates. I have seen several examples of how to fix this but they are all in C# and the application is in vb. Can anybody step me through this please as i sem to be missing something.

hello,

show me the examples that you found in C# ... i might be able to convert it back to VB for you ... =)


Ttry this online link for converting C# to VB Code...

http://www.kamalpatel.net/ConvertCSharp2VB.aspx


Hi

My conversion is below,

Protected Overrides Function LoadPageStateFromPersistenceMedium()As Object Dim viewStateAs String = Request.Form("__VSTATE")Dim bytesAs Byte() = Convert.FromBase64String(viewState) bytes = Decompress(bytes)Dim formatterAs LosFormatter =New LosFormatterReturn formatter.Deserialize(Convert.ToBase64String(bytes))End Function Protected Overrides Sub SavePageStateToPersistenceMedium(ByVal viewStateAs Object)Dim formatterAs LosFormatter =New LosFormatterDim writerAs StringWriter =New StringWriter() formatter.Serialize(writer, viewState)Dim viewStateStringAs String = writer.ToString()Dim bytesAs Byte() = Convert.FromBase64String(viewStateString) bytes = Compress(bytes) ScriptManager.RegisterHiddenField(Me,"__VSTATE", Convert.ToBase64String(bytes))End Sub
Public Function Compress(ByVal dataAs Byte())As Byte()Dim outputAs MemoryStream =New MemoryStreamDim gzipAs GZipStream =New GZipStream(output, CompressionMode.Compress,True) gzip.Write(data, 0, data.Length) gzip.Close()Return output.ToArray()End Function Public Function Decompress(ByVal dataAs Byte())As Byte()Dim inputAs MemoryStream =New MemoryStream() input.Write(data, 0, data.Length) input.Position = 0Dim gzipAs GZipStream =New GZipStream(input, CompressionMode.Decompress,True)Dim outputAs MemoryStream =New MemoryStream()Dim buffAs Byte()Dim readAs Integer = -1 read = gzip.Read(buff, 0, buff.Length)While (read > 0) output.Write(buff, 0, read) read = gzip.Read(buff, 0, buff.Length)End While gzip.Close()Return output.ToArray()End Function

And the original code was:

protected override object LoadPageStateFromPersistenceMedium()2 {3string viewState = Request.Form["__VSTATE"];4byte[] bytes = Convert.FromBase64String(viewState);5 bytes = Compressor.Decompress(bytes);6 LosFormatter formatter =new LosFormatter();7return formatter.Deserialize(Convert.ToBase64String(bytes));8 }9protected override void SavePageStateToPersistenceMedium(object viewState)10 {11 LosFormatter formatter =new LosFormatter();12 StringWriter writer =new StringWriter();13 formatter.Serialize(writer, viewState);14string viewStateString = writer.ToString();15byte[] bytes = Convert.FromBase64String(viewStateString);16 bytes = Compressor.Compress(bytes);17 ScriptManager.RegisterHiddenField(this.updVS,"__VSTATE", Convert.ToBase64String(bytes));18 }
thanks again

ViewState / PostBacks

Hi all,

Is there any way to update the viewstate actually on the page without having to reload the page?

I know that sounds a bit daft but I would be interested to know - I'm having some issues with my update panels / dynamic controls and this might help.

Hi,

normally the UpdatePanel keeps the viewstate in sync, something a lot of people dislike since that adds significantely to the total data transferred back and forth to the server.

I think your problem is more with the dynamic controls. Be sure to put them in the right eventhandler like Page_Init. Something you can try is to first remove the updatepanel and see if everything works. If it does you can integrate the updatepanel again and recheck.

Grz, Kris.


Hi Kris,

Thank you for your reply.

When you say that the update panel keeps the viewstate in sync, should I notice this on the page if I view source?

For example - lets say to keep things easy when my page loads I view source and there's 100 characters of viewstate, I then perform an action that'll change this, are we saying that the update panel has changed the page so that if I view source now I might see 150 characters for example?

My object that is held in viewstate I can access programmatically, ie, repopulate my object when needed from viewstate and everything is there - I was just wondering whether the actual characters in the view source are going to change or only if there's a full postback?


I doubt you'll see it in a ViewSource; I don't think most browsers reevaluate that after an async postback. You'll want to use the IE Dev toolbar or the Firefox Dom Explorer to get a runtime view of what's in there.


Hi,

another great tool would beFiddler.

Grz, Kris.


Thanks for the info about the additional tools chaps - appreciated.

My problem after further diagnosis seems to be this...

When a user adds a resource, I add the drop down menus using AJAX, the update panel updates, I store the select resource in the view state so that when the update panel updates again I can call back the already selected ones to dynamically rebuild those controls again.

My problem seems to be that when you select an item in the list it doesnt fire the onselectedindexchanged event, I'm completely at a loss why to be honest because I'm using the same function for the controls that are added to the update panel after the user has chosen a resource as I am for the pre-selected resources that come with a role - and thats working?

Any thoughts? I've attached a screenshot so you can perhaps get a better idea of what I'm trying to achieve...

Application Screen Shot


Well, I'm not sure how to solve the problem offhand; I tend to limit my use of updatepanels where possible. I'm not entirely sure at what point you're adding your controls based on your description; are you adding them using javascript on the client? That's what it sounds like. if that's the case, then you're not going to be able to do what you're trying to do b/c they don't exist on the server. If you're adding them on the server during the updatepanel's firing, then I'm pretty sure the upd won't recognize them (iirc, it loads all its triggers, etc, on the initial load during Init or PreInit of the page). You might be able to manually force an update by using the PageRequestManager.update() function on the client, and then wire the dropdown's event handler to a function that calls that; but I'm just guessing at this point.


Hi Paul, thank you for your reply...

To clarify what I'm trying to do then...

Looking at the screenshot above you'll notice two clear sections "Pre-selected resources" and "Additional resources".

My code gets the data for the role from SQL, and builds the 3 sets of drops downs (for access level and further detail) adding them to a table control.

I have them also in independent updatePanels, ie, one around each set of drop downs, when the user selects and access level in the first drop down menu (on the left) it'll run my code server side to update the items in the second drop down menu (on the right).

So in the screenshot, the top half of the page is working as expected, and also includes validators etc if nothing is selected on either of the menu's (left or right).

The "additional resources" is where it got more difficult...

When the user clicks on the "Add Resource Hyperlink" a popup window is launched which displays a list of all available resources as hyperlinks, each of the hyperlinks has a javascript call wired up so that when they are clicked it will place the ID of the resource into a hidden text box on the parent window. It also "clicks" a hidden button on the parent window.

My code then detects the click even and grabs the resource id from the hidden text field. I use this to then go and get all of the access levels for the resource and add a set of drop down menus to the "additional resources" part of the page, this has its own containing updatePanel.

The set of drop down menus are added with their own updatePanel as per the "pre-selected resources" section, the code to generate these is a generic function used by both.

I am then expecting the onSelectedIndexChanged event on the access level drop down (on the left) to fire when the user selects an item which in turn should then run my code to populate the further detail drop down menu (on the right) - this is what is currently not working - there are no errors, server or client side - simply nothing happens.

Initially I had a problem where I was adding the resource (with the drop downs) to the update panel and when I added the next one the first disappeared, this turned out to be because the server did not know anything about them as they were added client side, I got around this by changing my onSelectedIndexChanged code to add the selected resource to my userRegistration object held in viewstate, and then each time it updates the update panel it rebuilds the controls, thus any previously selected ones appear.

I hope this helps to clarify what I'm trying to do and where it isn't working, if it helps I'm happy to take a few more screenshots for each of the steps of the process to help further...


Any chance I can see the code related to those additional drop downs? PM is fine if you're not comfortable posting it here.

Also, use Fiddler to see if the event fires, but is not handled by the server, or it doesn't fire at all.

If it's fired, but not handled by the server, then you might have to do some manual inspection of the request to see if one of those dynamic controls fired it and then manually call the handler. If it's not fired, then you might have to do some .js hotness to get the controls properly wired up.

Paul


Hi Paul,

Thanks for your reply - no problem posting the code up - no need to PM - hadn't done it thus far as there's quite a bit of it...anyway...here goes...this should be most of the relavent stuff I think - if there's anything else let me know - last night I got as far as when you change the selected item in the access level (left hand drop down) nothing happens, but then on the second time you change the selection it fires something - not sure what as it then didn't display any controls - lol...looks like something might be nearly working...maybe...

Private Sub PopulateRoleBasedResources()' declare variablesDim userRegistrationAs UserRegistrationDim roleResourceCollectionAs RoleResourceCollection.SerializableRoleResourceCollectionDim roleResourceAs RoleResource.SerializableRoleResourceDim addSpacerAs Boolean' instantiate userRegistration =New UserRegistration(ViewState) roleResourceCollection =New RoleResourceCollection.SerializableRoleResourceCollection(userRegistration.RoleID)' iterateFor Each roleResourceIn roleResourceCollection' populate _iteration += 1' check position in collectionIf roleResourceCollection.AtEndOfCollection =True Then' populate addSpacer =False Else' populate addSpacer =True End If' create table rows for resource access levels and parameter options CreateTableRowsForResourceAccessLevelAndParameterOptions(AccessLevelParameterOptionsType.PreSelected, tblRegistrationPreSelectedResources, _iteration, roleResource, roleResource.AccessLevels, addSpacer)Next End Sub Protected Sub ddlResourceAccessLevelSelectedIndexChanged(ByVal senderAs Object,ByVal eAs System.EventArgs)Dim dropDownListAs DropDownListDim resourceAccessLevelIDAs GuidDim controlIterationAs String Dim requiredFieldValidatorAs RequiredFieldValidator' populate controlIteration ="" dropDownList = sender resourceAccessLevelID =New Guid(dropDownList.SelectedItem.Value.ToString())Select Case sender.id.ToString.Contains("AccessLevel")Case True controlIteration = Right(sender.ID.ToString, (Len(sender.ID.ToString) - 23))Case False controlIteration = Right(sender.ID.ToString, (Len(sender.ID.ToString) - 21))End Select' find our resourceParameter drop down list dropDownList = Page.FindControl("ddlResourceParameter_" & controlIteration)' populate PopulateResourceParameters(resourceAccessLevelID, dropDownList)' find our resourceAccessLevel requiredFieldValidator requiredFieldValidator = Page.FindControl("vldResourceAccessLevel_" & controlIteration)' validate requiredFieldValidator.Validate()End Sub Private Sub PopulateResourceParameters(ByVal resourceAccessLevelIDAs Guid,ByRef dropDownListAs DropDownList)' declare variablesDim sqlAs SQLDim resourceParametersAs Data.DataTableDim listItemAs ListItem' check resourceAccessLevelIDIf resourceAccessLevelID.ToString <>"00000000-0000-0000-0000-000000000000"Then' instantiate sql =New SQL' populate resourceParameters = sql.GetResourceAccessLevelParameters(resourceAccessLevelID)' check we returned some resourceParametersIf resourceParameters.Rows.Count > 0Then' populate dropDownList.DataSource = resourceParameters dropDownList.DataTextField = resourceParameters.Columns("ResourceParameterName").ColumnName.ToString() dropDownList.DataValueField = resourceParameters.Columns("ResourceParameterID").ColumnName.ToString() dropDownList.DataBind()' instantiate listItem = CreateListItem("00000000-0000-0000-0000-000000000000","Please Select") listItem.Selected =True' add list item to drop down list dropDownList.Items.Insert(0, listItem)Else' instantiate listItem = CreateListItem("00000000-0000-0000-0000-000000000000","None Available") listItem.Selected =True' add list item to drop down list dropDownList.Items.Add(listItem)' TODO: Send error to webmaster if no rolegroups have been loadedEnd If' housekeeping ' Dispose(sql)Else' clear all previously added resourceParameters dropDownList.Items.Clear()End If End Sub Protected Sub ddlResourceParameterSelectedIndexChanged(ByVal senderAs Object,ByVal eAs System.EventArgs)' declare variableDim controlIterationAs Integer Dim requiredFieldValidatorAs RequiredFieldValidator' populate controlIteration = Right(sender.ID.ToString, (Len(sender.ID.ToString) - 21))' find our resourceAccessLevel requiredFieldValidator requiredFieldValidator = Page.FindControl("vldResourceParameter_" & controlIteration)' validate requiredFieldValidator.Validate()End Sub Private Sub CreateTableRowsForResourceAccessLevelAndParameterOptions(ByVal accessLevelParameterOptionsTypeAs AccessLevelParameterOptionsType,ByRef tableAs Table,ByVal iterationAs Integer,ByRef enumeratorAs Object,ByRef enumerableObjectAs Object,ByVal addSpacerRowAs Boolean)' declare variablesDim tableRowAs TableRowDim tableCellAs TableCellDim dropDownListAs DropDownListDim listItemAs ListItemDim updatePanelAs UpdatePanelDim requiredFieldValidatorAs RequiredFieldValidatorDim requiredFieldValidator2As RequiredFieldValidatorDim accessLevelDropDownListIDAs String Dim parameterDropDownListIDAs String Dim accessLevelValidatorIDAs String Dim parameterValidatorIDAs String Dim resourceAccessLevelAs ResourceAccessLevel.SerializableResourceAccessLevel' populate resourceAccessLevel =Nothing accessLevelDropDownListID ="ddlResourceAccessLevel_" & iteration accessLevelValidatorID ="vldResourceAccessLevel_" & iteration parameterDropDownListID ="ddlResourceParameter_" & iteration parameterValidatorID ="vldResourceParameter_" & iteration' *** First table row *** ' *** First table cell *** ' instantiate tableRow = CreateTableRow() tableCell = CreateTableCell(40, HorizontalAlign.Left)' populate AddWebControlToControlCollection(tableCell, CreateImage(16, 1,"UI/Images/Misc/Shim.gif","","")) AddWebControlToControlCollection(tableCell, CreateImage(16, 16,"UI/Images/Misc/BulletPoint.gif","Bullet Point","*")) AddWebControlToControlCollection(tableCell, CreateImage(5, 1,"UI/Images/Misc/Shim.gif","",""))' add tablecell to tablerow tableRow.Cells.Add(tableCell)' *** First table row *** ' *** Second table cell *** ' instantiate tableCell = CreateTableCell(HorizontalAlign.Left)' populate tableCell.Text = enumerator.Name tableCell.Style.Add("font-weight","bold")' add tablecell to tablerow tableRow.Cells.Add(tableCell)' *** First table row *** ' *** Third table cell *** ' instantiate tableCell = CreateTableCell(HorizontalAlign.Left)' populate tableCell.Text =" "' add tablecell to tablerow tableRow.Cells.Add(tableCell)' *** First table row *** ' *** Fourth table cell *** ' instantiate tableCell = CreateTableCell(HorizontalAlign.Left)' populate tableCell.Text =" "' add tablecell to tablerow tableRow.Cells.Add(tableCell)' add tablerow to table table.Rows.Add(tableRow) tableRow =Nothing tableCell =Nothing' *** Second table row *** ' *** First table cell *** ' instantiate tableRow = CreateTableRow() tableCell = CreateTableCell(40, HorizontalAlign.Left)' populate tableCell.Text =" "' add tablecell to tablerow tableRow.Cells.Add(tableCell)' *** Second table row *** ' *** Second table cell *** ' instantiate tableCell = CreateTableCell(HorizontalAlign.Left) updatePanel =New UpdatePanel dropDownList =New DropDownList listItem =New ListItem("Please Select","00000000-0000-0000-0000-000000000000") listItem.Selected =True' populate updatePanel.ID ="upnAccessLevelParameter_" & iteration.ToString updatePanel.UpdateMode = UpdatePanelUpdateMode.Conditional updatePanel.RenderMode = UpdatePanelRenderMode.Inline dropDownList.AutoPostBack =True dropDownList.ID = accessLevelDropDownListID dropDownList.CssClass ="vam" listItem.Selected =True' create event handler ' AddHandler dropDownList.SelectedIndexChanged, AddressOf ddlPreSelectedResourceAccessLevelSelectedIndexChangedAddHandler dropDownList.SelectedIndexChanged,AddressOf ddlResourceAccessLevelSelectedIndexChanged' add listitem to dropdownlist dropDownList.Items.Add(listItem)'iterateFor Each resourceAccessLevelIn enumerableObject' instantiate listItem =New ListItem(resourceAccessLevel.Name, resourceAccessLevel.ID.ToString)' add listitem to dropdownlist dropDownList.Items.Add(listItem)Next' instantiate requiredFieldValidator = CreateRequiredFieldValidator(dropDownList.ID.ToString, accessLevelValidatorID,"00000000-0000-0000-0000-000000000000","<img class=""vam"" src="http://pics.10026.com/?src="UI/Images/Icons/Warning.gif"" style=""width:16px;height:16px;"" title=""Required information missing"" alt=""!"" />","Required information","UserRegistrationFurtherDetailStep3")' populate updatePanel.ContentTemplateContainer.Controls.Add(dropDownList) updatePanel.ContentTemplateContainer.Controls.Add(CreateImage(16, 16,"UI/Images/Misc/MandatoryField.gif","Required information","Required information","vam", 0, 0)) updatePanel.ContentTemplateContainer.Controls.Add(requiredFieldValidator) updatePanel.ContentTemplateContainer.Controls.Add(CreateImage(16, 16,"UI/Images/Icons/Information.gif","Click to view Access Level information","Information","vam", 5, 35))' instantiate dropDownList =New DropDownList' populate dropDownList.AutoPostBack =True dropDownList.ID = parameterDropDownListID dropDownList.CssClass ="vam"' create event handlerAddHandler dropDownList.SelectedIndexChanged,AddressOf ddlResourceParameterSelectedIndexChanged' instantiate requiredFieldValidator2 = CreateRequiredFieldValidator(dropDownList.ID.ToString, parameterValidatorID,"00000000-0000-0000-0000-000000000000","<img class=""vam"" src="http://pics.10026.com/?src="UI/Images/Icons/Warning.gif"" style=""width:16px;height:16px;"" title=""Required information missing"" alt=""!"" />","Required information","UserRegistrationFurtherDetailStep3") requiredFieldValidator2.IsValid =True' populate updatePanel.ContentTemplateContainer.Controls.Add(dropDownList) updatePanel.ContentTemplateContainer.Controls.Add(CreateImage(16, 16,"UI/Images/Misc/MandatoryField.gif","Required information","Required information","vam", 0, 0)) updatePanel.ContentTemplateContainer.Controls.Add(requiredFieldValidator2)' populate AddWebControlToControlCollection(tableCell, updatePanel)' add tablcell to tablerow tableRow.Cells.Add(tableCell)' *** Second table row *** ' *** Third table cell *** ' instantiate tableCell = CreateTableCell(HorizontalAlign.NotSet)' populate tableCell.Controls.Add(CreateImage(16, 16,"UI/Images/Icons/Information.gif","Click to view Further Detail information","Information","vam", 5, 5))' add tablecell to tablerow tableRow.Cells.Add(tableCell)' instantiate tableCell = CreateTableCell(HorizontalAlign.Left)' *** Second table row *** ' *** Fourth table cell *** ' populate tableCell.Text ="Empty cell"' add tablecell to tablerow tableRow.Cells.Add(tableCell)' add tablerow to table table.Rows.Add(tableRow)' add a spacer if requiredIf addSpacerRow =True Then' instantiate tableRow = CreateTableRow() tableCell = CreateTableCell(2, HorizontalAlign.Left)' populate tableCell.Text =" "' add tablecell to tablerow tableRow.Cells.Add(tableCell)' add tablerow to table table.Rows.Add(tableRow)End If End Sub

Ok - I've had some success!!

I ran it through in debug mode with a break point on the page load, this is where I have a test to see if we're posting back asynchronously and build the page depending on some factors.

What I noticed was that when I call my onSelectedIndexChanged event handler function I add the resource to the userRegistration object and then rebuild the controls on the page (iterating through those in my object) - but when I do any other form of postback (even if asynchronously) I wasn't calling this - and this was why they seemed to disappear.

So, I've amended the code to incorporate this and now I have the controls not disappearing, I've even managed to get them to fire and populate the further detail drop down menu (on the right) - the only minor thing to resolve now is where this is call from - as if I leave the code in the onSelectedIndexChanged event handler function then my controls get duplicated on the page, if I take it out then all but the most recently added one appear but I'm hoping this will be easy to resolve - get there though - and even my validators work - lol - gotta love OO!Big Smile


Glad I could help. seems like you'd want to pull the code in your onSelectedIndexChanged handler out into a helper function, and then have the OSIC handler perform inspection of the sender to determine whether to fire that version, or a different version that doesn't create duplicates. Alternatively, if you keep (as you suggested) your created 'stuff' in the state bag, then you should just be able to inspect the contents of the state bag to see what's there, and then add to it as needed, rather than blindly adding, if that make ssense.


Hi Paul,

Ok - I'm still struggling a bit with this...

The controls are being added which is a good thing - however, if I add one control, I can then use it and the OSIC event fires - great...

If I add more than one control then you seem to need to select 2 different values before it fires...I've followed this through in the debugger and I have a theory - but thats about it!

At the moment I've got the code that iterates through the resources in the userRegistration object as a separate sub, I call this when the page loads (based on certain criteria), so that all of the items are displayed, part of this process is to clear the table first, thus anything thats there is cleared, then all of the resources are rendered.

When the user adds a new one I call this sub again, as obviously I need to show the one they just added...

It looks as if the building of the controls twice might be causing the problem, whilst they have ID's that are set by me I get the feeling that its losing some reference from what had the OSIC event on the first fire, ie, nothing happens, then the page is rebuilt and the second time it seems to work - its very strange...

I'm not sure of the best approach now - I need to display whatever resources have already been added AND the one that has just been added and obviously have all of them firing correctly...

Any thoughts?


Hi Rob; got your PM; sorry I didn't respond earlier.

I'm not really sure based on your code what might be causing the problem; can you look at the rendered' page's source through a runtime tool like the IE developer toolbar and check the DOM tree and the attributes of each of your ddls to see what they look like at each step of the operation? If you have the site somewhere that's accessible, I'll look at it that way for you.

I'm also not entirely clear on the behavior you're describing. Let me repeat my undertanding and you can tell me where I'm mistaken: What you're experiencing is that when you have one dynamic dropdown on the page all is well. That is a ddl that is added after the initial page load. When you later add a second dynamic control, the first time you make a selection on it, nothing happens. the second time you make a selection on it, you get the expected behavior. Is that correct?


Hi Paul,

No worries, I just thought I'd give you a try on this as you helped me out last timeSmile

I dont have the developer tool bar installed, so I'll get it and install it, I've never used it before so I hope its intuitive - you've seen what I mess I can get into! hehe...

I think your description of your understanding was correct - albeit that obviously each time I try to fix this I change something and then that changes the outcome, but I typically then put it back to how it was and go around in circles...

I can confirm that if you only add ONE additional resource it seems to work perfectly, but I suspect that this is because the method to build the controls is being called twice, once in the page load, and once on the button click event, well actually 3 times then - the page loads, it tries to iterate through the collection of already selected resources but there aren't any, so its doesnt, then you select one, the javascript clicks the button, the ajax enables the .net method to be called which adds a resource object to my collection in the userRegistration object in viewstate, and then calls the method to build the controls. No doubt at some point here there's been a postback either full or async - async most likely, thus the same call to build the controls would have happened there too - thus I believe its called twice...maybe thats why if you only add one it works..

I have a line of code in the build mehtod which clears all rows from the current table, this was added to ensure that I didn't get duplicates on the page, if I remove this then I do get duplicates so felt it best to keep this in, so each time it will remove everything from the table, and then rebuild.

If I remove the call to build from the add resource method (fired from the button click) then I never see the most recently added object on the page, my code has added it to the viewstate though so on the next postback/async postback the build method is called and they all appear.

Regarding the number of times you have to select something in the drop downs my theory is that when its say the second control, its run the build method AFTER the page_init, .net doesn't know about the control althought it was added programmatically and is on the page - and thus I believe (probably wrong) it equally doesn't know about the eventhandler (made programmatically with addHandler) - therefore when I select an option it doesnt fire my event, instead it does the autopostback because this is set to true to try and enable the AJAX etc...as such when the postback is called it runs my build method which then takes the resources from the collection in my userRegistration object from viewstate and builds the controls - I think (although have almost lost the plot now) - at this stage the selected index change event DOES work because .net now knows about the controls...and as such the second drop down menu is populated...

I think thats about it...

ViewState and Atlas

Hi

I encountered a problem involving viewstate and PageMethods (web methods in an aspx page).

I was submitting some control values, only one control on the page is designed as a <asp:listbox />, the rest of the controls are generic HTML. While Atlas.js constructed the proxy to the PageMethod and the arguments (Web.Net.PageMethodRequest) the Atlas.js javascript does some sort of check on the page controls, in which viewstate is a hidden input, adding it to a dictionary (refer line 3495 in Atlas.js)

Some sort of exception is generated but no information is available to determine the source. The code behind to the PageMethod didn't get hit in debug mode and it wasn't until I inspected the request/response in Fiddler that I came across a message indicating a corrupted viewstate.

After disabling viewstate on the <asp:listbox> the request got through to my [WebMethod] in the code-behind.

There is a problem with PageMethods and viewstate, or have I missed something.

Craig

An update for those who might be encountering the same problem with altas (Jan-06 CTP) and ViewState.

As mentioned in my previous post, in the file Atlas.js on line 3495, a procedure adds to the variable bodyDictionary all 'submittable' HTML element e.g <input /> this includes <input type="hidden" /> which means that<inputid="__VIEWSTATE" /> is added to the bodyDictionary variable.

Next in the procedure, is a call Web.Net.WebRequest.createQueryString(bodyDictionary, ...);

This is where IMHO the viewstate corruption is occuring between the client service calls to the server. In my case, I make a call to a [WebMethod] which is contained in an aspx page. So my client function is something like this:

functionfoo() {
PageMethod.GetFoo('hello');
}

My aspx.cs [WebMethod] is like the following:

[WebMethod]
public string GetFoo(string text) {
return text+=" get foo";
}

My page wrapes a user control in an<atlas:UpdatePanel>the user control contains an<asp:Repeater>control.

Has anyone experienced this, or am I the lucky one? To avoid the error 500, I removed the check for HTML elements with a type of hidden. But I'm not sure if this is a good thing...

Craig

PS: I can post the stack trace for those who might be interested.


Further, using PageMethod seems to faciliate the viewstate corruption. for kicks I moved the [WebMethod] from the aspx page into an ASMX file, reversed my Atlas.js script hack and the viewstate problem has gone. I hope the PageManager is a little more robust in the rtm.


Hi,

I'm not able to reproduce the behavior that you described. Could you post the stack trace and also the relevant page code?

Hi Garbin

Stack Trace
[FormatException: Invalid length for a Base-64 char array.]
System.Convert.FromBase64String(String s) +0
System.Web.UI.ObjectStateFormatter.Deserialize(String inputString) +72
System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter.Deserialize(String serializedState) +4
System.Web.UI.ClientScriptManager.EnsureEventValidationFieldLoaded() +172

[ViewStateException: Invalid viewstate.
Client IP: 127.0.0.1
Port: 3520
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
ViewState: /wEWCAKbhpuAAgLEtM6pBgLN/7aVCAKe4MuSDQLL7+H/CgLL7 3/CgKs5ZucDgLNoqBMLo1Lj5/N S5y dQM87L I5JMzQ=
Referer:http://localhost/Unsd/COC/ExchangeRateView.aspx?countryCode=36
Path: /Unsd/COC/ExchangeRateView.aspx]

[HttpException (0x80004005): The state information is invalid for this page and might be corrupted.]
System.Web.UI.ViewStateException.ThrowError(Exception inner, String persistedState, String errorPageMessage, Boolean macValidationError) +116
System.Web.UI.ClientScriptManager.EnsureEventValidationFieldLoaded() +209
System.Web.UI.ClientScriptManager.ValidateEvent(String uniqueId, String argument) +67
System.Web.UI.Control.ValidateEvent(String uniqueID, String eventArgument) +106
System.Web.UI.WebControls.TextBox.LoadPostData(String postDataKey, NameValueCollection postCollection) +31
System.Web.UI.WebControls.TextBox.System.Web.UI.IPostBackDataHandler.LoadPostData(String postDataKey, NameValueCollection postCollection) +11
System.Web.UI.Page.ProcessPostData(NameValueCollection postData, Boolean fBeforeLoad) +408
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +6953
System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +154
System.Web.UI.Page.ProcessRequest() +86
System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context) +18
System.Web.UI.Page.ProcessRequest(HttpContext context) +49
ASP.exchangerateview_aspx.ProcessRequest(HttpContext context) in c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\unsd_coc\bdef81f1\ee1d3cb5\App_Web_ytigk7vl.8.cs:0
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +154
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +64

Page Code (aspx.cs)
[WebMethod]
publicExchangeRate GetExchangeRate(int countryCode,int year) {
returnCountryManager.Instance.GetExchangeRate(countryCode,
newint[] { year });
}

Page Code (aspx - javascript)
function GetExchangeRate(countryCode, year) {
// Call the server.
PageMethods.GetExchangeRate(countryCode, year, RequestCallback);
}

function RequestCallback(exchangeRate) {
// Bind the result to the controls.
document.getElementById("ctl00_contentPlaceholder_textboxYear").value = exchangeRate.Year;
document.getElementById("ctl00_contentPlaceholder_textboxIMF").value = exchangeRate.IMF;
document.getElementById("ctl00_contentPlaceholder_textboxUNOP").value = exchangeRate.UNOP;
document.getElementById("ctl00_contentPlaceholder_textboxOther1").value = exchangeRate.Other1;
document.getElementById("ctl00_contentPlaceholder_textboxOther2").value = exchangeRate.Other2;
document.getElementById("ctl00_contentPlaceholder_textboxNote").value = exchangeRate.Note;
}

Page Code (aspx - html)
<!-- Exchange Rate Control -->
<atlas:UpdatePanelID="updatePanelExRate"runat="server"Mode="Conditional">
<ContentTemplate>
<unsd:ExchangeRateControlid="exchangeRateControl"runat="server"/>
</ContentTemplate>
<Triggers>
<atlas:ControlEventTriggerControlID="buttonSave"EventName="Click"/>
</Triggers>
</atlas:UpdatePanel>

The ExchangeRate control is populated in the Page_Load event of the aspx Page by passing an array to a property accessor in the control, the array provides is the data source to a repeater. The ItemTemplate in the repeater contains a link to invoke the GetExchangeRate javascript in the page (above).

Hope this helps.

Craig


I don't know if its the same issue or not, but viewstate corruption is rampant in the QuickStart tutorials... There were several times where I ran 3 or 4 different "run this" tutorials in a row only to have the viewstate corruption error message appear on me. Sometimes it was fixed with a refresh of the page, sometimes it never went away.
hi Guys...
even i got the same problem when i put my [webmethod] in code behind.i tried removing type=hidden from atlas.js line 3495 and it is working.please let me know for the solution as we just can not remove any thing from coreatlas files even though doing the same results in expected output.

thanks
Jaideep

I tried a few things, but was not able to repro. Could you give this a try with the March CTP to see if it still happens?

thanks,
David


I have a similar problem with teh session state.

I have narrowed it down to a web user control that raises an event.

The code behind that implements the event sets the session var and then does a redirects.

on the redirect page the session state is blown away. cant figure out why

steps to reproduce

- create a web user control (define an event and raise it)

- create a page and place the wuc on it (trap for the wuc event and set a session var and do a redirect to 2nd page

- in 2nd page Page_load check the session state