WhoIsKB - Kevin Blakeley

Public WebLog WhoIsKb() { return "Random experiences with .Net" ; }

<July 2008>
SuMoTuWeThFrSa
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789


Navigation

Tools I Love

Subscriptions

Post Categories



ASP.net (RSS)

ASP.net
Control your view state

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.

posted Thursday, June 23, 2005 1:28 PM by whoiskb with 3 Comments

ASP.Net without web projects!

While listening to Fritz Onion today on his first web cast, he told us about a URL that just made my day:

http://pluralsight.com/wiki/default.aspx/Fritz.AspNetWithoutWebProjects

This is an article that I wish I found about 8 months ago!  It goes into details on how to setup asp.net appliations without using a web project from visual studio.  I converted one of my projects and it worked like a champ!  Debugging and all!

I am going to keep the settings this way for a while to see if I find any “Gotcha's“ and I will report back if I do.  In the mean time, if you have been using this method for a while and know of any gotcha's, please let me know.

 

 

posted Tuesday, November 09, 2004 8:48 PM by whoiskb with 0 Comments

ASP.NET 2.0 Directory Names

Check out this blog entry if you are interested in providing feedback on how the new asp.net directory names should be setup.  I know I have seen quite a bit of discussion on these names and how they should be configured through a config file, well now is your chance to provide more feedback to the product team....

 

posted Tuesday, September 14, 2004 11:43 AM by whoiskb with 0 Comments

ASP.net Tracing in a popup window

I just saw Dino's post on his wish list for ASP.Net tracing and saw he wanted the tracing window in a popup window.  This is something we wanted for our web apps as well, so here is how I tackled the problem. I know its not perfect and the output is still put out to the main page, but the reason why I had to come up with this scheme was because in our web apps we are using absolute positioning. When we did this our content was placed over the top of the trace div.

Here is the code.....

============== Parent ASPX Page =================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
 <HEAD>
  <TITLE>Parent Page</TITLE>
  <SCRIPT>
  function SetupTraceWindow()
  {
   var div = GetTraceDiv();
   if(div==null) return;
   
   win = window.open("Trace.htm","Trace");
   if(win==null) windown.status="The trace window was blocked.  Please make sure popup blockers are off.";
  }

  // Called by the child window to get the html of the trace output and also hides the trace output on the parent page.
  function GetTraceHTML()
  {
   var div = GetTraceDiv();
   if(div==null) return "";
   var html = div.outerHTML;
   div.style.display="none";
   return html;
  }

  // Returns the div that is created by the ASP.Net trace function
  function GetTraceDiv()
  {
   var div = document.getElementById('__asptrace');
   return div;
  }
  </SCRIPT>
 </HEAD>
 <BODY ms_positioning="GridLayout" onload="SetupTraceWindow();">
  <FORM id="Form1" method="post" runat="server">
  This is the parent page.
  </FORM>
 </BODY>
</HTML>

======================= Trace.htm =======================
<!DOCTYPE html public "-//w3c//dtd html 4.0 transitional//en">
<HTML>
<HEAD>
<TITLE>ASP.Net Trace Output Popup</TITLE>
<SCRIPT language="javascript">
function SetupTrace()
{
 var html = opener.GetTraceHTML();
 document.writeln(html);
 opener.focus();
}
</SCRIPT>
</HEAD>
<BODY onload="SetupTrace()">
<DIV id="myTrace"></DIV>
</BODY>
</HTML>

posted Tuesday, June 01, 2004 12:14 PM by whoiskb with 3 Comments

Dropdownlist does not allow child controls

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.

posted Thursday, May 20, 2004 1:48 AM by whoiskb with 0 Comments

Sorting the datagrid

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("&nbsp;","<img border=0 src=",Request.ApplicationPath,"/images/sortasc.gif",">");
 String imgDesc = String.Concat("&nbsp;","<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 &nbsp; 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 &nbsp; text in our header to force a space
   int pos = col.HeaderText.IndexOf("&nbsp;");
   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

 

posted Monday, April 19, 2004 12:31 PM by whoiskb with 0 Comments

Share session state across virtual directories

I just got done reading Peter's post about a limitation he ran into about sharing session variables across web applications, and thought I would blog about an approach we recently took with one of our web apps to get around this problem.

We got our solution from this MSDN article, which shows you how to separate out your web applications into smaller web applications. The first step is to create an IIS application and this is the root of your web application. Under this root, you create your smaller modules as virtual directories, but don't configure them to have their own web application. (now refer to the article to see how to make this friendly to VS.Net) Now, because the root is setup as a web application, this is the guy that manages your session state for all of the modules below it, and our session state can no be shared across all of the different modules.

Now I understand that this won't be for everyone, but in our case it has worked out great. We are currently building a pretty large web system that consists of various modules, and one requirement we would like to satisfy is to allow us to deploy each module separately but also be able to share session state across all of the modules. We have a main IIS root application and each module is setup as a virtual directory under it. The root, and each of the modules each has its own ASP.NET web project and can be compiled separately. This would allow us to only update specific modules when needed. So now when we make changes to just module A, we can build the web app for module A, plus all of its supporting assemblies.  By having all of the modules under the root, all of the modules can now also share session state.

Hope this makes sense, but if it doesn't the MSDN article will really clear things up since they provide good instructions on how to get everything configured.

UPDATE: Fixed the MSDN link

posted Wednesday, April 07, 2004 2:20 PM by whoiskb with 0 Comments

The Cookie Monster

While recently developing a web application, I came across an interesting problem that I haven't seen before.  Part of our application uses session cookies to keep track of data.  One cookie is actually set by ASP.net forms authentication, and we set a few others of our own.  Initially we had no problems with using these variables......

Then entered the fraameset.....

We recently had a user that was entering our site through a fraameset.  They had one of the fraames pointing to our site, and they said the site was unusable.  After setting up a quick test and tried to log into our site (which sets the authentication cookie), I kept getting redirected back to the login page which kind of hinted that the cookies were not being kept around.  I then found a knowledge base article, and found out that this was a design feature with Internet Explorer, http://support.microsoft.com/default.aspx?scid=kb;EN-US;323752

The problem arises when you have a fraame set in which the fraame points to a different website that uses a different top level domain.  In my test I had the fraameset hosted site.com, and one of the fraames pointed to mysite.com. 

I took the easy solution that the KB article mentions and added the  HTTP header to IIS and the problem was fixed.

BTW, I did not spell fraameset or fraame wrong.  The .text engine would not let me post with those words in the message.

posted Friday, February 20, 2004 5:19 AM by whoiskb with 0 Comments




Powered by Dot Net Junkies, by Telligent Systems