Environment: Microsoft Visual Studio 2019 Community, ASP.NET v4.8 web application project using VB.NET
Problem: I have an asp imagebutton which is used to indicate a status by changing the image each time it is clicked (red-amber-green-red). This is done using javascript:
btn.src = newImage;
This works fine. The imageurl is accessed using src in the html but the image is initially set in the code behind databind by setting the imagebutton.imageurl:
btn.ImageUrl = initialImage
On a postback (a save) I want to find the status by looking at the current imageurl.
Dim btn As ImageButton = CType(mainGrid.Rows(i).FindControl("btn"), ImageButton))
someval = btn.imageurl
The problem is that imageurl shows the value initially set, not the changed value. This weirdness seems to point to a bug in my code somewhere as obviously the imagebutton variable in the save code behind knows nothing about the imagebutton variable in the databind code behind.
Can someone confirm that imageurl in the postback should in fact match the changed src in the html?
Edit: I should say that I don't want to use server-side processing each time they click the imagebutton. I can make this work using a command argument BUT that leads to a database write every time they click. There are a dozen or so buttons on each row so I think that would be pretty slow in production.
The answer, provided by Albert D. Kallal, is that imagebuttons don't pass any changed attributes back to the code behind. Possible solutions are to 1) use an update panel, 2) change a paired hidden field at the same time (of a type that does pass the change back) or 3) use ajax to update the db after the change. I used option 3.
Related
I am receiving the following error message after an HTTP POST on an ASP.NET form hosted inside a UserControl:
Failed to load viewstate. The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request. For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request.
Here's additional info:
I'm running .NET 4.5 RC
It's an Umbraco 4.7-based website
On my local dev machine the form works perfectly
This error only occurs on the staging server which has .NET 4.5 (only), MSSQL 2012 Express, IIS 7.5, Windows 7 (I know, it's not a real server yet, one day maybe...)
The server is not part of a web farm (or garden, tho that should be irrevelant)
The user control does render controls dynamically
I have applied all the latest service packs.
I have run out of ideas now! I have even restarted it and also performed a richual over the server involving a song and a special dance to no avail.
What is important when you are adding controls dynamically is on which event you are adding them.
If you added controls on events that occur after load, they will be part of the viewstate you send to the client.
You will have to add those controls again before LoadViewState is called.
If you run into cases where the decision of which controls to add is itself stored in the ViewState or the value of a control, then remember even before the ViewState is loaded, this data is available in Request.Params
Refer the asp.net page life cycle
I just added EnableViewState="false" to my page placeholder and its gone. Hope it works for u as well.
This Error Mainly Occurs during View state Change: From One Template To other Template like in case of Item Template, Edit Item Template, in Controls like Form View, List Views, Detail View, Grid View in ASP .net (all frameworks);
While Changing from control states say Item Template ---> Edit Template
the followings were going to alter
1) Controls will change (its ID & states)
2) Its Positions will change.
While Transformation of view if any post back occurs you will get Error as
Failed to load viewstate. The control tree into which viewstate is
being loaded....
if you are using separate control for data-binding like (button,link_button_Image_button events) you will get this error reported !
To avoid this error >>> Once state changes from one template to other within method you call data source binding ( Don't call during click or any post backing events ).
OK, so the answer is literally: "Set up a new server with all the same software as the last one and try again" and it works now.
I add "name" attribute with the same value as id, then this problem is gone.
<input type="button" id="extractBomInfoBtn" name="extractBomInfoBtn" value="Extract" class="button textonly" />
I had the same issue. This issue was at client end but it didn't occur in my local system.
After hours of googling, i had written EnableViewState="false" to my table tag in aspx page which has all the dynamic controls and then i removed all the viewstate variables and instead i created some hidden textboxes in the aspx page and accepted DB values into them in code behind and used them throughout my code. It then solved my problem.
But still, i couldn't figure out what was exactly the problem.
In my case I was manipulating the .Text property of a asp:Literal on page load which was causing the issue. In all other cases this never caused me a viewstate error but in this particular case I was changing the .Text value to an html element.
The following caused the error:
<asp:Literal ID="SvgIcon" runat="server" />
SvgIcon.Text = "<svg version=\"1.1\" id=\"Layer_1\" bla bla />"
I was able to resolve the error by adding EnableViewState="false" explicitly to the control:
<asp:Literal ID="SvgIcon" runat="server" EnableViewState="false" />
Check if you have the binding method of the control directly in your page load event. This can cause this problem.
You can add new PlaceHolder per UserControls
OR
You can set enableviewstate=false on the control , if you dont need viewstate
In my case I had a grid view with (OnPageIndexChanging) event
and when I click on a page nothing will happen until I click it twice!
I was refreshing the data source before setting new page index.
This is what I was doing wrong
grd.DataSource = data;
grd.DataBind();
grd.PageIndex = e.NewPageIndex;
This is the right way
grd.PageIndex = e.NewPageIndex;
grd.DataSource = data;
grd.DataBind();
This can happen if you override SaveViewState in your control but don't override LoadViewState.
So I actually ended up discovering that the list of entities I was binding to was not in the same order as the controls in ViewState! I'm still working thru a cleaner solution, but my code is working with ViewStateEnabled = true by having the method which reconstructs my dynamic controls (called from Page_Load) do it differently if !IsPostBack.
Ultimately, I will probably need to fix my sorting algorithm for my nested dynamic controls, but suffice it to say: if you are using the same pattern as I am, of using a List to generate/bind to dynamic controls, and that order is fluid or changing, try comparing Request.Params to find the keys that are relevant to your control hierarchy, and see if they match the order of your List. That solved my issue. Kudos to #nunespascal!
In short, I am dynamically generating all but one tab in an AjaxToolkit tab control, and then populating that with a couple layers deep of placeholders and regular controls (textboxes, dropdownlists, etc), so that's why it's complicated to get the order of everything correct.
Although this is very old question, I had visited this as I got the similar issue. But my issue was generated just because I have added a javascript code in Master page in head tag. That javascript code is reading a value of Session["KeyName"] ,
Code is like below -
$(document).ready(function () {
var allowOpenInNewTab = false;
allowOpenInNewTab = '<%# Convert.ToString(Session["AllowOpenInNewTab"]).ToLower() %>' == 'true';
if (!allowOpenInNewTab && window.sessionStorage.tabId != '1') {
alert("This page is not allowed to be open in another tab, sorry we can not load the page!!");
}
});
When I remove above code then everything was running smoothly but if I keep adding this part of code, it was giving this error of
Failed to load viewstate. The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate...
Finally I found the solution like if I move my javascript code from head to just before the end of the body tag.
So solution that worked for me was moving javascript code (which is reading Session value from Server tags) to just before end of body tag.
I have a dynamically built table on the page load of my web page containing textboxes with defaults that can be changed by the user. There is also some validation on the user input values (e.g., input can not be less than zero). When the user submits the table, only valid inputs are stored, and the page is refreshed pulling the stored values to populate the table when it is rebuilt. For some reason the textboxes will still display invalid inputs after submitting and reloading the page even though they are not persistent, and this problem does not happen for labels.
Is there something specifically built into the textbox control causing this issue? Is there somewhere storing the state, perhaps (I tried setting the ViewState flag to false)? Is this just some part of the page lifecycle?
The textbox is built in a method called from the Page_Load event
void Page_Load(object sender, EventArgs e)
{
//page initialization...
ValidateData(); //This is where the current data is verified, and stored if valid
BuildTable(); //This takes that stored value for the text
}
void BuildTable
{
tbTable = new Table();
tbRow = new TableRow();
tbCell = new TableCell();
TextBox tb = new TextBox();
tb.text = some stored value;
tbCell.Controls.Add(tb);
tbRow.Cells.Add(tbCell);
tbTable.Rows.Add(tbRow);
divFromPage.Controls.add(tbTable);
}
If more information is necessary to help with this issue, just let me know.
Edit :
After reproducing your problem i came to the following conclusion.
I believe the problem is not the viewstate but asp is just repopulating these values because the form data which you submited has the same name as the input element which you are returning.
Even though you generate them dynamicly since you add them to the same div the result is always the same. This leads me to 2 solutions :) :
My solution nr 3 still stands , i tried it out and on button click redirecting works as intended with no posted data creeping back into my textbox.
This statement takes care of that :
Response.Redirect("~/test.aspx");
Alternativly you could generate a random ID to make sure the inputfields names you are returning are different from the ones that were submited. You wouldn't have to change all the names but if the table ID for example is different the entire table won't get populated with the submitted data anymore.
Be aware that you might need a if(IsPostBack) in your pageload because your data will be lost right after pageload(unless you handle the saving before that)
If you are doing a postback asp.net uses it's viewstate to maintain all the textbox,textfields and all other form elements(including input type hidden).
I currently see 3 solutions to your problem :
You could do what ivowiblo suggested, before you load the data from the database( i assume you do) you could wipe all the textfields. On a first time visit this will be pointless off course since they are blank. But after a postback it will actually wipe the textfields.
You could disable the viewstate on those textboxes so asp will not persist the state. I'm not sure why your test didn't work but it should work. If you choose this approach feel free to edit your question with some actual code
My personal favorite : Redirect the page. In stead of just returning the result and causing a postback to the page do the following : after the user hits the save button you can save the data and then do a Response.Redirect to your current page. The browser will be redirected to the page and no viewstate will be involved.
Just figured this out, kind of a D'oh moment, I just populated the data in the PreRender event and it works just fine, thanks for all the input.
I am building a modal box as a custom server control and I want to have a property on the modal box TargetControlID that specifies the element that will show the modal when clicked. I've set the property up in the modal box and in the code behind I use the following code block (which I've tried in several different places
If (_targetControlId <> "") Then
Dim targetControl As WebControl = Me.Page.FindControl(_targetControlId)
targetControl.Attributes.Add("onclick", "test1();")
targetControl.Attributes.Add("onclick", "test2();")
End If
What happens is that targetControl always winds up to be NULL, and causes the page to crash when I tried to add attributes to it. I've double checked the spelling of the targetControlId and I am specifying a control that is runat="server". What is the proper way for a server control to access other controls on its containing page?
Thanks,
Mike
First of all, I should point out that the behavior you're looking for already exists in the ModalPopupExtender that comes with the free, open-source AjaxControlToolkit. I'd recommend you just use that. If you're still sure you want to write your own, then I'd recommend at least taking a look at their code to see how they go about it. ExtenderControlBase.FindControlHelper is a good place to start.
I have a simple ASPX page based of a master page. On the ASPX page, I have two drop downs and a button. When pressing the button, I want to execute some javascript. To do this, I have used the Button's attribute collection (Add("onclick", script)).
My script looks like this:
string script = "return confirm ('You have selected' + document.getelementbyid(DropDownList1).value + document.getelementbyid(DropDownList2).value)");
Button1.Attributes.Add("onclick", script);
The drop down box element names are spot on, but why doesn't the javascript fire? The button's click event (obviously) gets fired when I click the event, but nothing happens.
This is being done in C#. If I use ASPX and write a basic javascript function in the ASPX markup, intellisense doesn't even come up with a value property for documentgetelementbyid. Why? My browser is fully js enabled (Firefox) as I had this working before but when I added the masterpage and based my ASPX page of that, everything went pear shaped.
Why doesn't the above script works?
Thanks
had you try adding the client ID
string script = "javascript:return confirm ('You have selected' + document.getelementbyid('"+DropDownList1.ClientID+"').value + document.getElementByid('"+DropDownList2.ClienID+"').value)");
I'm not entirely sure of your environment but you may want to take a peek at the source that's being generated by your ASP page. Master pages add a prefix to control names "breaking" the getElementById call. Take a look at the following: http://west-wind.com/weblog/posts/4605.aspx to see if that corrects your problem.
case sensitive: document.getElementById?
Shouldn't DropDownList1 and DropDownList2 be in quotes?
When some JavaScript code seems to not work, it's probably because the syntax is invalid.
To prevent that you can:
Validate your current statement (I'm thinking that maybe the ids of the drop-downs should be surrounded by single quotes).
Try with a simple alert first and see if it works -- alert('Hello world'); --
If not, try playing with the OnClientClick property of the button.
You also should have the "javascript" in your attributes:
string script = "javascript:confirm ('You have selected' + document.getElementById(DropDownList1).value + document.getElementById(DropDownList2).value)");
Button1.Attributes.Add("onclick", script);
I have a ASP.NET 1.1 application, and I'm trying to find out why when I change a ComboBox which value is used to fill another one (parent-child relation), two postbacks are produced.
I have checked and checked the code, and I can't find the cause.
Here are both call stacks which end in a page_load
First postback (generated by teh ComboBox's autopostback)
Postback call stack (broken)
Second postback (this is what I want to find why it's happening)
alt text (broken)
Any suggestion? What can I check?
It's a very specific problem with this code, I doubt it will be useful for someone else, but here it goes:
A check was added to the combo's onchange with an if, if the condition was met, an explicit call to the postback function was made.
If the combo was set to AutoPostback, asp.net added the postback call again, producing the two postbacks...
The generated html was like this:
[select onchange="javascript: if (CustomFunction()){__doPostBack('name','')}; __doPostBack('name','')"]
First thing I would look for is that you don't have the second ComboBox's AutoPostBack property set to true. If you change the value in the second combo with that property set true, I believe it will generate a postback on that control.
Do you have any code you could share? Double post backs plagued me so much in classic ASP back in the day that it was what finally prompted me to switch to .NET once and for all. Whenever I have problems like these for .NET, I go to every CONTROL and every PAGE element like load, init, prerender, click, SelectedIndexChanged, and the like and put a breakpoint.
Even if I don't have code there, I'll insert something like:
Dim i As Integer
i = 0
I am usually able to pinpoint some action that I wasn't expecting and fix as needed. I would suggest you do that here.
Good luck.
Check Request.Form["__EVENTTARGET"] to find the control initiating the postback - that may help you narrow it down.
Looking at the callstacks, and some Reflectoring (into ASP.NET 2 - I don't have 1.1 handy) - it looks like SessionStateModule.PollLockedSessionCallback is part of the HttpApplication startup routines. It may be possible that your app is being recycled - I'm pretty sure an event gets written into the Event log for that.
My only other suggestion would be Fiddler or something on the client to capture HTTP traffic.
This is very old post, but people still looking at this for solution exactly same as I did last week.
Like Grengby said Double events are primary reasons - but removing one of them is not allways an option. Atleast on my case and I had to resolve this on 3rd party's application.
I added following script and amended ASP form on masterpage:
<script>var Q = 0;</script>
<form id="Form1" runat="server" onsubmit="Q++; if(Q==1){return true;} else { return false;}">
This seems to be working and please forward your comments.
Arun
http://www.velocityreviews.com/forums/t117900-asp-net-multiple-postback-issue.html