C#
C#
I just came across a post on the asp.net forums about wanting to control how view state is saved with a page. As we all know by default view state is rendered as a hidden element on the page, but that can easily be changed and you can set your pages up so that viewstate is saved to the cache, session, or the database.
The first step I would suggest is to create a base page for your aspx pages and override two methods, LoadPageStateFromPersistenceMedium and SavePageStateToPersistenceMedium. As you can tell by their names, these are the two methods responsible for determining how view state is actually handled in the page.
The following is what I put together for the SavePageStateToPersistenceMedium method. This method will take the viewstate object that is passed in and run it through a special formatter to serialize the object. According to MSDN, the LosFormatter object is designed for highly compact ASCII format serialization and serializes the view state for a WebForm page. Once the object has been serialized, I then save the viewstate to a session variable. I used a session variable for demonstration purposes only, but once the object has been serialized, it can be saved to session, cache, or a database. Here is the code for the SavePageStateToPersistenceMedium method:
protected override void SavePageStateToPersistenceMedium(object viewState)
{
// Saftey check to ensure we have a valid object
if( viewState==null) return;
// Instantiate the formatter used by the framework to serialize viewstate
LosFormatter formatter = new LosFormatter();
// We need a stream writer to write the viewstate text to
StringWriter writer = new StringWriter();
try
{
// Serialize our view state to the string writer
formatter.Serialize( writer, viewState );
// Save the view state to session state
Session["ViewState"] = writer.ToString();
}
catch
{
throw new HttpException("Invalid view state");
}
finally
{
// Clean up
writer.Close();
}
}
The next step is to override the LoadPageStateFromPersistenceMedium and load the viewstate data from the same location it was saved to in the SavePageStateToPersistenceMedium method. This is where we take the data out of our session object and then deserialie the data. Here is the code for the LoadPageStateFromPersistenceMedium method:
protected override object LoadPageStateFromPersistenceMedium()
{
object viewStateObj = null;
// Instantiate the formatter used by the framework to serialize viewstate
LosFormatter formatter = new LosFormatter();
// Grab our viewstate from session
object sessionViewState = Session["ViewState"];
try
{
// Deserialize the object
viewStateObj = formatter.Deserialize(sessionViewState.ToString());
}
catch
{
throw new HttpException("Invalid view state");
}
return viewStateObj;
}
Once you implement this code, you will notice that a hidden viewstate field is still dumped out into your page, but its empty.
We had discussion today at work about how we should use regions, and it was funny to see everyone had a different opinion on the matter. Here is what I usually do:
Class - Wrapped around the class
Private Members
Constructors
Properties
Public Methods
Private Methods
Base OverRides
Interface Definitions
What do you do?
I got an interesting error today, but first some background. I am creating a server control that inherits from DropDownList and internally I also add an image server control next to it. I add this image dynamically by trying to add it to the controls collection of the dropdownlist. When I try to do this I get an error saying that you cannot add controls to the dropdownlist controls collection.
When I look at the dropdownlist in reflector I noticed that the CreateControlsCollection has been overridden and an emptycontrolcollection is created. What this emptycontrolcollection does is enforce the rule that you cannot add controls to the control collection.
Now, I was able to override the CreateControlsCollection for my control, but I am curious as to why they did this. Does anyone know why? Its strange because I did this same functionality with a textbox and had no problems.
This weekend I worked on implementing sort logic in the datagrid. I wanted to use the built in sorting that the datagrid provided and was a little dissapointed. I will post the code below but I was suprised by two things:
- No indication of which direction the sort should be
- No easy way to get to the column header the sort came from
Not that these two were show stoppers or anything, but I guess I was just expecting those two things to be there.
But anway, I have posted the code below that I came up with to implement bi-directional sorting in my datagrid. This code will perform the sort on my dataview plus attempt to add an image to the column header. If anyone has some feedback on an easier way to do this in case I missed something, please share.
Here is the code behind code, and these are just the routines that are involved in my sort logic:
private void grdContacts_SortCommand(object source, System.Web.UI.WebControls.DataGridSortCommandEventArgs e)
{
String sort = e.SortExpression;
String vsort = GetSortViewState();
// If the current sort expression is the same as the one in view state that means they are resorting
// the same column and we need to sort in the opposite direction. Once we add the DESC flag to the sort, if
// the user clicks on the same column again, it won't won't match and the sort expression will be reset to
// the same column but with ASC order.
if(sort==vsort)
{
SetColumnSortIcon(sort,false);
sort = String.Concat(sort," Desc");
}
else
{
SetColumnSortIcon(sort,true);
}
// Save off our sort so that on a post back we can determine what direction the sort should be if they click the same column
SetSortViewState(sort);
BindPageData(sort);
}
private void SetColumnSortIcon(String sortExpression, bool ascending)
{
String imgAsc = String.Concat(" ","<img border=0 src=",Request.ApplicationPath,"/images/sortasc.gif",">");
String imgDesc = String.Concat(" ","<img border=0 src=",Request.ApplicationPath,"/images/sortdesc.gif",">");
// Loop through all of the columns in the datagrid and compare the sort expressions to find a column match.
// Once the column match has been found, lets add our image HTML to the header to show which column is being sorted on.
foreach(DataGridColumn col in grdContacts.Columns)
{
if(col.SortExpression==sortExpression)
{
String text = col.HeaderText;
// The is an indicator to know if we have already added an image tag. If it exists in the header that means
// we already have an icon in the header and the current column was previously sorted and the direction of the sort
// has changed. This could cause a problem if we use the text in our header to force a space
int pos = col.HeaderText.IndexOf(" ");
if(pos>-1) text = col.HeaderText.Substring(0,pos);
if(ascending)
col.HeaderText = String.Concat(text,imgAsc);
else
col.HeaderText = String.Concat(text,imgDesc);
break;
}
}
}
#endregion
#region Private methods
private String GetSortViewState()
{
object obj = ViewState["sortexpression"];
return (obj==null) ? String.Empty : (string)obj;
}
private void SetSortViewState(String sort)
{
ViewState.Add("sortexpression",sort);
}
private void ClearSortViewState()
{
ViewState.Remove("sortexpression");
}
#endregion
This just came across one of the MSDN blogs I watch and thought I would share just in case anyone missed it.
http://blogs.msdn.com/csharpfaq
The C# team, along with members of the C# Community, are answering Frequently Asked Questions (FAQs) via a web log (blog) set up at http://blogs.msdn.com/csharpfaq. Entries from that site will be displayed on MSDN through this page with only a short delay due to caching.
We are currently taking our current flagship product which is an illustration system for life insurance companies and doing a complete redesign/rewrite for .Net. In our original system we used Active Reports for the reporting tool and have been fairly happy with it.
Moving forward though we have found that Active Reports.Net actually runs slower than its non .Net version. Our reporting was always the slowest part of our system and we were hoping to figure out ways to speed up our reports, so that news was not promising.
I was curious as to see what others are doing in regards to reporting for their .Net applications. Enterprise solutions such as the new SQL Server reporting tool is not an option as the license and framework must support royalty free distribution to desktops. The output must support PDF, and having an RTF option would be nice.
Okay C# gurus, I could use your help on this one. Here is what I am trying to do. This is my class hierarchy:
MyImageButton
ImageButton
Image
Here is what I am trying to do. In MyImageButton I am going to override AddAttributesToRender on ImageButton as there is some logic in the ImageButton implementation that I don't want executed. At the same time though I still want to call AddAttributesToRender on Image. When I am done doing my own implementation of AddAttributesToRender in MyImageButton, I want to skp executing the method on ImageButton, but still want to call the method on Image.
How do I do this?