C# - Persisting A Collection Backed By Viewstate In A CompositeControl?
Apr 28, 2010
Maybe it's been a long day but I'm having trouble persisting a collection backed by the ASP.NET ViewState in a CompositeControl. Here's a simplified version:
public class MyControl : CompositeControl
{
public Collection<MyObject> MyObjectCollection
{
get {
return (Collection<MyObject>)ViewState["coll"] == null ?
new Collection<MyObject>()
: (Collection<MyObject>)ViewState["coll"];
}
set { ViewState["coll"] = value; }
}
}
public partial class TestPage : System.Web.UI.Page
{
protected void btn_Click(object sender, EventArgs e)
{
myControl1.MyObjectCollection.Add(new MyObject());
}
}
When the button is clicked, the event hander btn_Click executes fine, but the setter for MyObjectCollection never gets called, hence the new MyObject() never gets persisted.
I've got a master page with a section for subnavigation links on it:
<div id="sub_nav" runat="server"></div>
I programatically populate this with Hyperlinks when my main asp:Menu data is bound depending on the address of the page I'm on.
This works fine and all my correct submenu stuff shows up on each page. The problem is that when one of these pages does a postback, I lose all the links that were in my sub_nav div.
Now, I could just populate the div with links every time regardless of whether the master page load is a postback or not, but I figured there is a better way of doing this. I was thinking enabling the viewstate on the div and links inside it might persist them through postbacks, but apparently that is not how viewstate works.
I have a control (say, a DataGrid or a ComboBox) which is a child of a user control. I want to DataBind it on every request, rather than have it's state persist through ViewState. I need to leave EnableViewState=true however. This means, I think, that I need to call DataBind before TrackViewState() is called.
I read the fantastic blog post TRULY Understanding ViewState and it answers my question in 4. Initializing child controls programmatically. However, the article's solutions are less-than-ideal: create child controls dynamically (I'm not and can't -- too much existing code), use a 3rd party CodeExpressionBuilder (would much prefer this was in code-behind), and use OnPreInit (which "doesn't help you what-so-ever if you are developing a CONTROL").
I read this article first to try to solve this issue, but I am already loading the controls in the Init phase of the page, yet viewstate is not persisting. Any ideas as to why? (Of note is that this is for a custom module in DNN and I do have some AJAX update panels on the page, though this section is not within an update panel, for what it's worth.)
As an overview of what I've got:
1. LoadControl.ascx - based on reading query string parameters, determines whether to load the master or the detail .ascx. 2. Master.ascx 3. Detail.ascx
In my master control I dynamically load either a master or detail sub-control in the page_Init. The detail page has a treeview control and then uses a multi-view control to display the panel associated with the depth of the node selected on the tree. On the panel being displayed I have a cascading ddl within a detailsview control which initiates a postback to select the child ddl based on the parent ddl selection. However, when the page refreshes after the postback, both ddls have resorted to their default selection.
What is interesting however, and I just realized this as I am typing, is that the Treeview is populated when the page comes back from the postback, so that is only possible if viewstate is being persisted right? (See the page_load code and you'll see that Call PopulateRootLevel(intTreeUserID) which populates the treeview, is not called on postbacks....hmmm.
Any ideas as to why the treeview maintains viewstate but not my ddls???? But though the tree is populated, I do have to explicitly select the node again and set the panel that the detailsview control is on to visible again too....
When exactly is the view state accessible from the .Viewstate property of a control? From my observations, the closest event is on the Page.PreLoad event (at Page.InitComplete, Viewstate is still unavailable).
However, for controls that implement the IPostBackEventHandler interface the LoadValue() method is called and the .Viewstate collection is available (this occurs after Page.InitComplete and before Page.PreLoad).
Does anyone know of any additional events that can be used to know when Viewstate is available? Or any tricks (not excluding reflection on private/protected/internal members) that can be used to know if the Viewstate has loaded or not?
I have an ASCX control which is a special dropdownlist. I add that control dynamically to the page and fill it with data. This control has a postback that will change the contents of a second dynamically created standard dropdownlist.
When I change the selection on the first dropdown, the indexchanged fires and I get new data and attempt to place it in the second dropdownlist's items collection, by first clearing it then filling it with new data.
This works fine the first time a change the selection, but when I select a second time the following error is thrown:
The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request.
I'm not adding or removing new controls in the fired event, only changing data. And again, it works the first time, but doesn't subsequent times.
If I disable stateview on the child control, then the control just doesn't get updated with data at all.
I have created a composite control that has some basically functions. I would like to be able to take that composite control and reuse the code.How do I do this? I have created a class and inheriated from my cc
public class PasswordTextBox : RoundedTextBox
now if I add another property to the new cc everything is over however nothing is rendered on the page.
public class MyControl : CompositeControl { private DropDownList myList; protected override void CreateChildControls() { base.CreateChildControls(); myList = new DropDownList(); myList.AutoPostBack = true; this.Controls.Add(myList); if (!Page.IsPostBack) { myList.DataSource = MyBLL.SomeCollectionOfItems; myList.DataBind(); } } }
I find that the items in the list persist properly, but when a different control is rendered and then this one is rendered again, the last selected item is not persisted. (The first item in the list is always selected instead)
Should the last selected item be persisted in ViewState automatically, or am I expecting too much?
I already have ASP.NET hosting, but I'm not sure how to run my application off Neo4j, since it requires a Java stack.
It seems my only options are:
Get separate Java/Linux hosting, and install Neo4J there, utilizing it as a database server. Get Neo4J-as-a-service, (akin to what MongoHQ does for MongoDB users) but I haven't had any luck finding providers. Move my whole application to Mono and then put it all on Java/Linux hosting and install Neo4j.
I was recently asked to speed up a C#/ASP.NET/SQL Server business app website. Since I just started, I don't know too much about the internals. So where do I start? Sight unseen, what is the single most important thing affecting performance on a system like this? Database tuning? Hardware? Individual page optimization? What is the first thing you'd look at? EDIT: After I actually do the work, I'll come back and post the answer. ;)
EDIT again: "Profile" is currently the most-voted answer, and I agree that that is clearly what one should do. But I was looking for guesses/experience as to what the profiling results would show, so I don't think that answer counts...
I have a list of objects that I want to bind to a gridview. Creating that list and binding it works fine for most of the public properties in that list.
There are some objects contained in each of those objects... for instance there is an Address object.
object.Address.Line1;
object.Address.Line2;
When I bind this to my gridview, I have no issues with stuff like object.DateRegistered, but how can I access things like object.Address.WhatEverProperty? I always get this error:
"A field or property with the name 'xxx.xxxx' was not found on the selected data source."
Background:I'm building a custom control as a base class that derives from CompositeControl. It consists of a FormView, a ObjectDataSource and a CRUD-Button Series (Create, Read, Update, Delete - Buttons). I'm loading the different FormView templates within the deriving classes dynamically from file with Page.LoadTemplate().
Class structure:
TabControlBase:CompositeControl
Employer:TabControlBase
Applicant:TabControlBase
Each deriving class knows the specific template-paths for loading FormViews templates.
The ObjectDataSource is connected with a DAL using a Select and an Update Method. The Select-Method works fine: When loading the CompositeControl the data of the DAL are shown in the Labels of the embedded FormView (ReadOnly-Template). When I'm switching to Edit Mode the data also are displayed in the TextBoxes (Edit-Template).
The problem occurs when I'm trying to update data using the "Save" - Button: The connected DAL-Method is calling properly, but the parameters all are NULL.Tree structure of this custom control:
All controls will be added dynamically in the base class "TabControlBase" within the overridden CreateChildControls - method. The CreateChildControls method is called by the deriving classes e.g. Employer after setting specific properties e.g. templates, object data source methods etc.The control is placed in a simple abc.aspx-Page. What I detected so far on PostBack
- When I'm looking at the ViewState Collection within the OnLoad-method of the abc.aspx the ViewState-Collection is Null (Count = 0)
- It seems that the control tree is empty. I'm not able to find any control using a proper working recursive FindControlMethod
- Only the Page.Request Collection shows the expected controls
Conclusion for now:It seems that the CompositeControl "forgets" the values of the FormView TextBoxes on PostBack. It seems it has to do with ViewState Management.
Now here is the weird thing. First i am running it locally on the built in vs2008 web server.I load my control in fine, do a postback from a linkbutton, locally on my machine it all works fine, no issue.However when it goes onto my host, it falls over with the message:
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.Now i also load controls dynamically and use postbacks and things in the admin area of the site...and that works fine, however my front end just keeps failing? See the code behing below:
I have an ASP.NET app with lots of textboxes all over the page that need updating at various points through program execution.
These textboxes actually belong to a certain class, so for easy updating I thought I could create a Dictionary(Of string, object) and add the control.ID and the control to it and then for updating do something like this:
(in case of updating textbox.text):
[code]....
However the text property of the textbox does not actually get updated. I'm mainly trying to avoid having to manually do textbox.text = somestring for each one of my textboxes every time I have to update them.
I have been getting this error a lot lately with some of my users, and I had a couple of concerns with view state and I have read so many articles but I am still lost..
1. I use masterpage on all the pages and I need viewstate for some of the pages but..
There is a page where a user will fill out the information and then submit this data to a cgi server, and it is where I get most of the Client Disconnected errors, what would happen if I disable viewstate when they click on that button?
Now when a user browses from one page to another, does the view state from the previous page get deleted? If not how would I delete it?
Does the master page have its own viewstate? Would I be able to make sure none of items on my master page are using the viewstate?
I have a shopping cart page (Cart.aspx) that has a button that will (sometimes) post to a third party payment gateway, if payment is necessary. The payment gateway will process the payment and then do a silent post to my website (Order.aspx) so I can update the order status.
Order.aspx always throws an invalid viewstate error, even though viewstate is disabled on the page.
What's happening is that Cart.aspx (which has viewstate enabled) posts to the payment gateway, and the gateway will post it back as part of the silent post. Even though Order.aspx has viewstate disabled and validation disabled, it still tries to validate the __viewstate field it's being given.
I know setting EnableViewState=false will disable the rendering of the __viewstate field, but if another page provides the field, shouldn't it still skip validation? I tried calling ViewState.Clear() on the Page_Init event of Order.aspx, but ViewState is apparently empty. how to get around this? I don't want to disable ViewState on Cart.aspx (in some cases it may be necessary), but I can't figure out how to clear it on Order.aspx.
I know that if I have set a cookie on a previous request, it will show up in my Request.Cookies collection. I want to update my existing Cookie. Are the cookies from my Request.Cookies collection already copied to my Response.Cookies collection? Do I need to add a new cookie with the same key using Response.Cookies.Add(), or do I need to use Response.Cookies.Set()?
I have just gotten a very odd error and I can't explain, or trace it out. My forum entity maintains a list of child forums. The list is internal, and exposed as an ienumerable, along with some methods like AddChild, FindChild and RemoveChild. Now to the code:
[Code]....
I have stepped through this several times, testing values along the way. It works perfectly, so I cannot explain the error. If a parent forum id is given, forumRepository.Update(parent) runs with no errors, it just doesn't actually save the new child to the db.
Incidentally... until I restart VS2010, the nhibernate session actually THINKS it HAS worked, and the new record shows on the page.
I'm building a web application that has a particular model representing some events. Users need to be able to add N number of people to a given event. Choosing people is handled by a partial view.
I'm trying to build a menu that displays when users click "add a person" to the event. Because the event hasn't been filled out completely yet, there is nothing in the database to persist between requests.
I also have validation logic on the event page.
My proposed solution is to add the form to search or add for people on the event form itself and have a submit button that sends the values that have been added back to the server, where I can store them in ViewData or Session.
Unfortunately, doing this flags the validation.
My second solution is to load a partial view responsible for loading the UI to add/search for a person. I could add a little code on the method in the controller that returns a partial view storing the existing data in a session variable or viewdata. Trouble is, I have to submit the form to do it--again tripping the validation!!!
I'm wondering if perhaps I chose the wrong tool to do this...because in webforms, there would probably be a postback and you would just perform an operation on that postback. I'd like to avoid rewriting the application in webforms and am wondering if there are ways I'm overlooking in ASP.NET MVC.
Alright, so here's my basic ASP.NET page setup: I've got a page with a GridView that has ContentTemplates in it. You can add a row and edit/remove rows at any time. There's a "New" button that creates a new row.
All of this data is bound to custom data objects. So if I have a GridView of "People" and each row has "FirstName", "LastName", and "Gender" (with TextBox and DropDown controls), I then have a "Person" object which has public properties for "FirstName", "LastName", etc. I have the binding set up correctly, and I can push data into the GridView from the object, and I persist the object with the Session variable. My page lifetime structure looks something like this:
Page_Load: Loads the List(Of Person) from Session()
Any events fire, and modify the List(Of Person).After any event, the List(Of Person) gets saved back into Session(), and is then DataBound to the GridView (and any subsequent fields are also DataBound, such as the DropDownList.
My question is: Whenever I fill in rows in the GridView, and then add a new row (there is no database saving going on whatsoever), my fields clear out and don't persist across PostBacks. So, how can I persist my custom data objects with databinding across postbacks?
In this instance I can't load the datagrid in page_init as the results of the datagrid are determined by a checkbox and the checkbox would always be set to true during page_init to the viewstate not being loaded.
I have an OnItemDataBound event on the datagrid that dynamically creates controls and later on I want to access the value of some of these controls (e.g. a text box)
Of course the problem is I can't access these controls values as they don't persist over a postback.
I am new to ASP.NET MVC and I am using ASP.NET MVC 2. I am trying to implement the following feature and I need your expertise on this:
Authentication is Windows Authentication. Every user has at least one country associated to his/her account that he needs to manage.When a user navigates to the site we have to look up his/her associated country and persist it somehow (session?).With every call to the backend we need to pass the country as a filter. When a user has more than one country associated to his/her account, we need to display a dropdownlist on the site and the user should be able to change the "current" country at any time. I have a couple of questions:
Where exactly in the lifecycle in the ASP.NET MVC framework should I retrieve the country or countries for the currently logged on user and where should this be persisted? In ASP.NET I would solve this by creating an intercepting filter using a HttpModule to set the Countries in the session state. What is a good way to implement this in ASP.NET MVC 2? (strongly typed session state wrapper?, magic strings?)Should I put a dropdownlist for the selection of the countries in my masterpage? How can I make sure that the current country remains selected in this dropdown?How can I make sure that with every call to the backend the country is passed, should I use an action filter?