Thursday, August 9

Validation and Agile Principles

I had earlier posted a javascript version of the
trim method, since a prebuilt one is not available.
But while watching Peter blum's DNRTV episode,
he showed that a prebuilt Trim method is available only when the method is used as (set as)a client side validator of the customvalidato control.

txtVal .value = ValidatorTrim(txtVal.value);

To hook up an additional control to the
ControlTovalidate use:


All credit goes to Peter Blum and DnrTV, blogging only for future reference purposes.

Also, ValidatorEnable(clientID) to enable/disable validators on the client side.

What I find funny is that these functions don't find a mention in the Professional series of not have I come across these in forums/blogs I browsed up till now. I wonder how one is supposed to find out helpful things like these.

Also here is a list of Agile principles mentioned by Venkat on DrntV episode on agile design

DRY - Don't repeat yourself
YAGNI - You aren't gonna need it
OCP - Open Closed Principle
LSP - Liskov's substitution principle
DIP - Dependency inversion principle ( used in creating enumerators for various classes such as ArrayList, queue...)

Will expand on these as time goes.

Amazing shows, hail dnrtv.

Labels: , ,

Monday, July 16

Using HTTP Handler for dynamic image generation

I was working on a project recently that needed bar charts to be created dynamically. We were not using sql reporting for this project. The bar chart needed to be changed/ updated based on certain criteria chosen from date controls, dropdowns etc.

One of the ways to achieve this is to create the image server side, store it on the disk on server and set the ImageUrl property of the image on the page to that saved image and send it to the browser.
This approach works but leads to addditional maintenance tasks, such as cleaning up old images, managing disk space etc...

One of the short comings of the image control Vs the image control in WinForms is that it lacks a property called "Bitmap" which allows you to assign a dynamically generated bitmap to the image control.

The only property exposed is the "ImageUrl".

I heard about http handlers and modules in podcats from polymorphic podcasts where Miguel Castro was explaining the use of HttpHandler to process certain file types.

Here is a formal definition from msdn : "An ASP.NET HTTP handler is the process (frequently referred to as the "endpoint") that runs in response to a request made to an ASP.NET Web application. The most common handler is an ASP.NET page handler that processes .aspx files. When users request an .aspx file, the request is processed by the page via the page handler.

HTTP handlers have access to the application context, including the requesting user's identity (if known), application state, and session information. When an HTTP handler is requested, ASP.NET calls the ProcessRequest method on the appropriate handler. The handler's ProcessRequest method creates a response, which is sent back to the requesting browser. As with any page request, the response goes through any HTTP modules that have subscribed to events that occur after the handler has run."

Scott Hanselman says : "Remember, an HttpHandler is the kind of thing you want to use when an HttpRequest is going to return a file or image to the browser. Basically anything other than a standard page. True, you could use a page, remove all the HTML from the ASPX part, and return stuff in Page_Load, but that's not really what pages are for, right? Also, Pages are themselves an HttpHandler (returned by PageHandlerFactory) so why not write your own HttpHandler?"

The processRequest for our bar chart image handler looks like this.

public void ProcessRequest (HttpContext context)
mPresenter = new ChartsPresenter(this);

When the bitmap generation is completed, we output the bitmap in this fashion

context.Response.ContentType = "image/gif";

We associate the ImageUrl property of the image to the http handler created to output the bar chart. Here is an abstract base class for creating http handlers that return proper error codes in case of problems. Phil Haack wrote it.

Wednesday, July 11

Databind dropdowns to Enums

Here is how you do it.

   20     private enum ReportTypes : int
   21     {
   22         ByVendor = 1,
   23         ByCategory = 2,
   24         ByType = 3
   25     }
35 protected void Page_Load(object sender, EventArgs e)
   36     {
   37         if (!IsPostBack)
   38         {
   44             ddlReportTypes.DataSource = Enum.GetNames(typeof(ReportTypes));
45 ddlReportTypes.DataBind();
   46         }
   47     }
   48     protected void ddlReportTypes_SelectedIndexChanged(object sender, EventArgs e)
   49     {
   50         ReportTypes rType =
   51             (ReportTypes)Enum.Parse(typeof(ReportTypes), ddlReportTypes.SelectedValue);
   52         switch (rType)
   53         {
   54             case ReportTypes.ByVendor:
   56                 break;
   57             case ReportTypes.ByCategory:                
   60                 break;
   61             case ReportTypes.ByType:
   62                 break;
   63         }
   64     }

Wednesday, July 4

Web.Config Gotcha

Midway into the project we sometimes realize that the intellisense in the web.config has vanished all of a sudden. The culprit being this line.

<configuration xmlns="">

Removing the xmlns attribute from the configuration tag brings back the intellisense for the Web.Config.

10 <configuration>

I saw this on one of the dnrtv shows, so credit goes to the author Miguel Castro.


Tuesday, July 3

Setting up Windows Authentication for Intranet Websites

 Recently I was put on a project that needed to harness the built in windows security for user authentication. Idea was to allow access only tousers of subscribed to certain groups. Once authenticated, based on the group the user is subscribed to, I needed to perform custom actions. 

The configuration started with the Web.Config. I added the authentication andauthorization sections to the Web.Config, specifying the authentication type and the groups authorized to access the site.

We deny access to anonymous users. Also, with the "Impersonate clause" we tell ASP.NET
to run using the permission/priveledges of the authenticated user
instead of the default asp_net user.

   37         authentication mode="Windows"        
   38         authorization
   39             allow roles="MSDomain\Buyers,MSDomain\Clerks,MSDomain\Receivers"
   40             deny users="*"            
   41         authorization
   42         identity impersonate="true"        
In order to be able to find out whether a user belongs to a particular group and to get a list of groups a user is subscribed to, we needed to
specify a "roleManager" config section and set the default provider to "AspNetWindowsTokenRoleProvider". Until this is done, the any code written
to check whether the user is part of a group/list of groups will not work.
"Role Manager" helps us manage groups(roles) and perform group based authorization
in the applicaion. We need the role manager to help us identify the groups of which the authenticated user is a part of and perform actions like wise.
Msdn article about role management says:
"The main benefits of using role manager are that it allows you to look up users' roles without writing and maintaining code. Additionally, the 
role providers offer a consistent way for you to check the role membership of your users, regardless of the underlying data store. Therefore, 
if your role store were to change tomorrow, you would only need to change the configuration settings to make your code work."

 roleManager enabled="true" defaultProvider="WindowsTokenRoleProvider" >

The default role providers are as follows:
1. SqlRoleProvider
 - role information kept in SQL Server
2. WindowsTokenRoleProvider
 - read-only provider that retrieves role information for a 
   Windows user account based on the account's Windows security 
   group membership
3. AuthorizationStoreRoleProvider
 - used if your application uses Authorization Manager (AzMan)
In my case, all I needed was to redirect user to corresponding portion of the site depending on their role, hence read-only role provider was
Msdn article says "The Windows security system acts as role store for this 
provider, so no additional configuration is required to set up the role store"
Once the user is authenticated, we need to check if the user is part of a particular group, if yes, then perform the custom action.
Below is the code required to validate whether a user is part of a inranet group.

  120         if (User.IsInRole   (WindowsGroupSettings.SettingFor.Buyers))
  121         {
  122             if (this.LoadPricesForBuyer != null)
  123             {
  124                 _buyerName = User.Identity.Name;
  125                 LoadPricesForBuyer(this, EventArgs.Empty);
  126             }
  127         }

To get a list of groups a user is part of use the following code:

  140         if (!IsPostBack)
  141         {
  142             gvRoles.DataSource = Roles.GetRolesForUser(User.Identity.Name);
  143             gvRoles.DataBind();
  149         }
Notice that I have used the WebNavigator, MVP pattern in this project. :)
I am having a torrid time fighting the fonts/html in post that contain code copied using copySourceAsHtml, 
especially code containing tags.

Labels: , ,

Thursday, June 28

ASP.Net FormView Control.

I was posed with the problem of a showing a list of data, displaying the details of a particular enry in the list and letting the user edit/update the entry, all on one page. I have seen such an scenario implemented with gridview with an "Edit" button as a column on the gridview and displaying the details on a modal popup. the modal popup would be either a "showModalDialog" based window or an Telerik RadWindow.

I wanted to specifically avoid having popups due to cross browser issues (did not have Telerik suite available for this project). To implement all of this functionality on a page I decided to user the Master-Detail mode with either the GridView-DetailsView or the GridView-FormView.

I srated off with a DetailsView by using TemplateFields for editable fields. soon, I realized the I had no control over the layout of the DetailsView and since I wanted to keep evething in the 1024X768 boundry, I decided on using the FormView.

FormView is very much like the DetailsView, it displays data item by item with paging support. What it offers you over the DetailsView is the ability to control the layout of the elements of the Detail and it also aleviates the need to implement an TemplateField for eahc and every field that needs to be edited. 

It basically has an ItemTemplate & an EditTemplate, the contents/layouts of which are totally in the developers control.
  319         asp:FormView ID="fvExceptionDetails" runat="server"/asp:
  320         AllowPaging="true" DataKeyNames="Oid" 
  321         OnModeChanging="fvExceptionDetails_ModeChanging" 
  322         OnPageIndexChanging="fvExceptionDetails_PageIndexChanging" 
  323         OnItemUpdating="fvExceptionDetails_ItemUpdating">
  324             ItemTemplate
  325             /ItemTemplate
  326             EditTemplate
  327             /EditTemplate
  328         FormView>
Since I am well versed with the event model of the GridView, I felt FormView would be similar to use and implement. But it is a bit different than the GridView and here are the events that need to handled in order for the FormView to work.

Each entry in the list displayed in the GridView was associated with zero or more detail entries that needed too be displayed in the FormView. Hence use of paging was obvious choice and had to have an handler in place for the PageIndexChanging event. 

  261     protected void fvExceptionDetails_PageIndexChanging(object sender, 
  262         FormViewPageEventArgs e)
  263     {
  264         fvExceptionDetails.PageIndex = e.NewPageIndex;
  265         DataBindExceptionDetails();
  266     }

The ItemTemplate had a LinkButton that had an CommandName="Edit" that when pressed should transform the FormView in the "Edit" Mode. so had to handle the ModeChanging event. Since I had did not want the user to move to anoher while editing, I disabled the Paging when in this mode. Also, I found that it was critical to DataBind() again in this even handler.

One thing to note would be that, in order to be able to access any of the elements inside the EditItemTemplate, the FormView has to be in that mode before you try and find the control using .FindControl("txtComment"). Hence the first statement in the ModeChanging event handler is the the .ChangeMode() method call.
  267     /// 
  268     /// event invoked only when mode changed through UI.
  269     /// 
  270     /// 
  271     /// 
  272     protected void fvExceptionDetails_ModeChanging(object sender, 
  273         FormViewModeEventArgs e)
  274     {
  275         fvExceptionDetails.ChangeMode(e.NewMode);
  276         if (e.NewMode == FormViewMode.Edit)
  277         {
  278             fvExceptionDetails.AllowPaging = false;
  279         }
  280         else
  281         {
  282             fvExceptionDetails.AllowPaging = true;
  283         }
  284         if (e.NewMode != FormViewMode.Insert)
  285         {
  286             DataBindExceptionDetails();
  287         }
  288         SetJSonclickAttribute();
  289     }

The EditTemplate contained 2 buttons at the end, namely the "Update" and "Cancel". In order to implement the "Update" functionality I had to have implement the ItemUpdating event handler. 

  322     protected void fvExceptionDetails_ItemUpdating(object sender, 
  323         FormViewUpdateEventArgs e)
  324     {
  325         //perform update logic here.
  326         fvExceptionDetails.ChangeMode(FormViewMode.ReadOnly);
  327         fvExceptionDetails.AllowPaging = true;
  328;/span>         DataBindExceptionDetails();
  329     }  

I hope this implementation detail helps. One thing to note would be that I was not using an ObjectDataSource/SqlDataSource to populate the Detailsview.

Sunday, June 24

ASP.Net Page Cycle

Understanding the ASP.Net page cycle is important and helpful in cases where you need to make changes to a control/ add a conrol/ change the master page at runtime, etc..

Here is the sequence of events and a brief description of the critical ones. I haven't had the chance to use of all of them as yet.

Order top to bottom

PreInit (method: Page_PreInit)

Themes and master pages are applied between PreInit and Init, hence PreInit is the last place to programtically modify the selected theme/masterpage. When implmenting "Nested Master pages" while maintaining the ability to see pages in design mode in VS 2005, one needs to set the the change the page's current master page ( the base master page) to the nested master page using this event.

This event is called before any state is restored from the
client response. It is used to prepare the Page for processing the request. Dynamic controls can be added in this event.
Child controls are created between this event and the "InitComplete" event if it is a postback. Also, Control/View State is loaded if it is a postback.

Most commonly used event. It is used to initialize control values on a GET request (!IsPostBack). It is called after
the control/view state has been restored in the Init event on a POST request (IsPostBack) before control passes to the specific event that caused the postback.
To be used to move code from the PreRender event,
the place to make last minute changes to controls.
Used to make any post-event modifications to the controls (Last place to make a change before they get rendered). Recently, I created an editable gridview consiting of 2 columns, one a "State" dropdown and the other "Type" dropdown whose content needed to be changed based on the state selected. I had a Telerik RadAjaxPanel around the Grid and wanted to change the content of the "type" dropdown based on the selection in the "State" dropdown. I had specifically used the PreRender event to tie the "State" dropdown to the "Type" dropdown for every row in the Grid.



Tuesday, June 12

Safari Beta 3 for PC released

I am excited, Apple has released Safari Beta 3 for the Windows. Though it crashed on my machine and I still haven't been able to see it run on my machine, I did see it running on my colleague's win xp box.

A substantial amount of education related community use the mac's and we had a lot of requests to make the sites "Safari" compatible.

This is a big player entering the pc browser market and should make things interesting.

Get it at Safari Beta 3 for PC

Saturday, June 9 Release mode Request timeout

On one of the projects, the administrator triggered of an event that created a flat file based on the contents of a database. This task needed around 10-20 minutes to complete. The task completed fine when in debug mode but never in release mode.

Upon talking to an Architect in the company it dawned upon me that there ASP.NET has something called "Request Timeout" (seperate than Session timeout) and this varies between the debug and the release mode. For the debug mode, the duration is a year while for release mode the request timeout is 90 seconds. Hence the abrupt request termination.

He pointed me to this:
Code Better: Peter Gekko: Timeout of an page

In short the code looks like this:
  279     protected override void OnInit(EventArgs e)
  280     {
  281         timeOut = Server.ScriptTimeout;
  282         // Give it 5 hour = (3600 * 5) = 18000 seconds
  283         Server.ScriptTimeout = 18000;
  284     }

This task can be completed using an ASP.NET Async page or by spawning a separate thread/process. I will make a post on that experience. Till then, this is workable.

Friday, June 8

Javascript gotcha

I recently ran into an issue with JavaScript where the script tag was ended with

Please overlook the missing "<" at the start of the script tags, since blogger understandingly has issues with script tags.

script src="../jscalender-1.0/calender.js" />
script src="../jscalender-1.0/calender/look.js" />
script src="../jscalender-1.0/calender/feel.js" />
script language="javascript" type="text/javascript">
function showCalender()

In spite of the rendered page containing the above script blocks, the showCalender function was not found and I kept getting a runtime javascript error: Object not found.

IE provided no clues about what is happening, finally when I looked at the source in Firefox with the color scheme, it dawned upon me that only the first script tag is being recognized while the rest are being ignored.

When I changed them to:
script src="../jscalender-1.0/calender.js"> /script>
script src="../jscalender-1.0/calender/look.js" > /script>
script src="../jscalender-1.0/calender/feel.js" > /script>
script language="javascript" type="text/javascript">
function showCalender()

So the moral is, close the JavaScript tags with /script> even though the /> might work in certain cases, it baffles you in cases like this.

Saturday, June 2

Books and Tree Surgeon

I am almost about to finish Joel on software. It is a fun book for developer and actually puts a smile on your face. I really liked his style of writing and presenting this experiences.

He says on recruiting, he only looks for 2 qualities in "Smart" and "gets things done".

I also like his "Joel Test" for evaluating employers. Quoting him:

1.Do you use source control?
2.Can you make a built in one step?
3.Do you make daily builds?
4.Do you have a bug database?
5.Do you fix bugs vefore writing new code?
6.Do you have an up-to-date schedule?
7.Do you have a spec?
8.Do programmers have a quite working conditions?
9.Do you use the best tools money can buy?
10.Do you have testers?
11.Do new candidates write code during their
12.Do you do hallway usability testing?

Also interesting is his idea about "hallway usability testing", which I actually implemented on a recent project. Its amazing how much input you get from fellow developers, their criticism, ideas to make the ap better. Hallway testing will stay with me forever.

I recently bought Code Complete, Jeff Atwood swears by this book. I want to read this book, its a big one. He considers it as the bible for all software developers.

I went to Barnes and nobles to read a book called Head First Design Patterns, I really liked the book and concepts were explained so beautifully. I just read about the "Strategy Pattern" and loved the way they presented the materials. I liked the line "Just because you know every OO concept doesnt mean you know how to use they".
some of the concepts I can still remember are
Encapsulate everything that changes
Use Composition over inheritance
Code to Interfaces and not implementations.

I came accross an amazing tool called "Tree Surgeon" which creates a development tree for you. just give it a project name and "voila" it creates a development tree for your project. One of the criticism received from David Heinemeier Hansson was that gives you a clean slate when you start with a new project. One has to be knowledgeble enough to setup the testing framework, business layer, build project. If you are new to .Net and not fortunate enough to have a good mentor, you would probably end up with a bloated project. Tree Surgeon does all that for you.

I am going to try and use it in some home project, probably a project to do an existing project using the MVP pattern. I will report my findings.

It will also introduce me to NAnt build system. I have only been using VS 2005 for building my projects uptill now.

Friday, June 1

IIS User

It might be a 101 but this week it struck me that the user under which IIS runs differs in WinXP and Win 2003. I was always under the impression that IIS runs under the local aspnet account (hostname\ASPNET).

Well, it turns out that it runs under ASPNET in XP (which most developers have) but runs under "Network Service" in Win 2003 which most servers have. I was setting an old website for maintainance purposes and the IIS user needed write permission to a certain folder (for ActiveReports PDFs to be written) .

Cassini, the internal web server for VS 2005 seemed to have access to that folder fine. I then setup a virtual dir for this project on my local IIS and gave ASPNET user write access and it worked. It took me a while to realise that under Win 2003, IIS runs under "Network Service".

Anyways, here is an article about it.

How To: Use the Network Service Account to Access Resources in ASP.NET

Wednesday, May 23

Mozilla Blogspot Issue

I am having this weird issue with Mozilla not able to display the html spurted out by CopySourceAsHtml utility and it happens only with the first post with html created by CopysourceAsHtml.

IE displays the posts correctly. Will have to look into this.

Compact Framework : Table Exist Method

In PDA based database applications one has to sometimes pull database/tables from the host machine/server onto the PDA (such as specific insurance agent's collection data). The procedure used is Remote Data Access (RDA). Compact framework has a stripped down version of the framework and some functionality available in the full framework isn't present on it.

I had a condition where I needed to I needed to check if a certain table existed on the pda database and if not then pull it from the server. I needed a table exist method and wanted to avoid the try catch code block which I have seen in use to derive that a table doesn't exist if you get a exception on something like this
'select (count(*) from premiums;'

I knew there would be a cleaner way to know if a table exist in a database or not.

Here is the method :

We query the meta data and get a clean answer, no try/catch needed derive the answer.

  430         /// 
  431         /// Queries the information schema to find whether a table exists or not
  432         /// 
  433         /// 
  434         /// 
  435         private bool TableExists(string table)
  436         {
  437             bool retAnswer = false;
  438             try
  439             {
  440                 int exist = (int)ConnectionManager.DBInfoConnection.ExecuteScalar(
  441                     "SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='" + table + "'");
  442                 if (exist == 1)
  443                     retAnswer = true;
  444             }
  445             catch (Exception ex)
  446             {
  447                 GenericLogger.Error("Could not query database for list of tables", ex);
  448             }
  449             return retAnswer;
  450         }
Please ignore the non use of SqlParameters. I had to add this as a maintainence method in an 
2-3 years old app and when you have to decide between your urge to make drastic(essential) 
changes to a system and the number of hours that have been alotted 
to this task, I think pragmatism wins.

Sunday, May 20

Visual Studio Must have tools & blog roll

If you are in ASP.NET development you are sure to stumble upon Scott Hanselman, the author of Professional ASP.NET 2.0. Recently I have started reading his blog reliously. Here is his list of tools and VS 2005 addins that are a must have and not to be missed.

Scott Hanselman's list of power tools

He has a important take on blogging. He rightfully contends that you will have returning audience only if your blog content is well formatted/indented and easy on the eyes.

I have started using the CopySourceAsHtml VS2005 plugin to do code blog posts. As you can see, I need to clean up old code posts on this blog and use the tool above to have the posts easy on the eyes.

I also like Jeff Atwood's writing, he says make it a habit to blog atleast once a week and make a commitement, since interpersonal and communication skills are so important and needs to honed with time. He writes on human factors in software development.

You can't miss Joel Spolsky author of the blog Joel on Software. His books are hilarious and fun to read.

I listen to Craig Shoemaker as often as I can. His show/blog is essential for every developer. He has the knack to explain beautifully the why/how/where approach for a solution.
Most podcasts/screencasts assume you know about things, while he explains things from the ground up.

One cannot miss the blog of the ASP.Net guru Scott Guthrie for ASP.Net tricks, tips, hacks, patches and advice.

I like to read blog by Jean Paul Boodhoo for knowledge about Test Driven Development and pattern based development.

I also sometimes refer to Scott Mitchel's blog. Scott, is a ASP.NET guru and consultant. He has an excellent series on "Working with Data in ASP.NET 2.0".

I will be editing this list this week, it is no way near completion.

Thursday, May 17

Sanitization against Sql injection attacks.

Here is what I use to sanitize my text input before inserting into DB. Most of the code is from a msdn article on how to avoid sql injection attacks.

   29         /// 
   30         /// make search text input sql safe.
   31         /// 
   32         /// 
   33         /// 
   34         private static string SafeSqlLikeClauseLiteral(string inputSQL)
   35         {
   36             // Make the following replacements:
   37             // '  becomes  ''
   38             // [  becomes  [[]
   39             // %  becomes  [%]
   40             // _  becomes  [_]
   42             string s = inputSQL;
   43             s = inputSQL.Replace("'", "''");
   44             s = s.Replace("[", "[[]");
   45             s = s.Replace("%", "[%]");
   46             s = s.Replace("_", "[_]");
   47             return s;
   48         }

   49         /// 
   50         /// make text input sql safe
   51         /// 
   52         /// 
   53         /// 
   54         private static string SafeSqlLiteral(string inputSQL)
   55         {
   56             return inputSQL.Replace("'", "''");
   57         }

   58         /// 
   59         /// convert '' to ' when returning to the user, Remember, only to be used
   60         /// when returning strings to user.
   61         /// 
   62         /// 
   63         /// 
   64         private static string Desanitize(string output)
   65         {
   66             return output.Replace("''", "'");
   67         }

Wednesday, November 29

Group Number in SQL Reporting Services

Found this after lot of searching.

I was grouping data in a table in a SQL report. I could successfully add row numbers to the details of the group but was unable to add row numbers to group header.
Something like this

1 ClaimID1

2 ClaimID2

3 ClaimID3
The following expression helped adding the row number for the groups
=RunningValue(Fields!ClaimID.Value, CountDistinct, Nothing)

Friday, November 3

javascript Trim method

Javascript has no trim() method that is required all the time.

This script will strip starting and ending spaces for you..

   72 // JScript File
   73 //javascript left & right trim similar to stringObj.Trim() in C#
   74 function trimAll(sString)
   75 {
   76     while (sString.substring(0,1) == ' ')
   77     {
   78         sString = sString.substring(1, sString.length);
   79     }
   80     while (sString.substring(sString.length-1, sString.length) == ' ')
   81     {
   82         sString = sString.substring(0,sString.length-1);
   83     }
   84     return sString;
   85 }

Tuesday, October 3

Detecting Session Timeout in Asp.Net

Alas post after a while. I wanted to detect session timeouts and redirect the user to the logon page with the appropriate message.
I stumbled upto this code (it works) which helps detect a session timeout in asp.Net.

One needs to follow the common BasePage pattern and inherit all the pages from this common page.
All the common functions can be put in this page.

/// This overriden method helps handle Session timeouts.
/// Credit to author.

   84     /// <summary>

   85     /// This overriden method helps handle Session timeouts.

   86     /// </summary>

   87     /// <param name="e"></param>

   88     override protected void OnInit(EventArgs e)

   89     {

   90         base.OnInit(e);



   93         //It appears from testing that the Request and Response both share the 

   94         // same cookie collection.  If I set a cookie myself in the Reponse, it is 

   95         // also immediately visible to the Request collection.  This just means that 

   96         // since the ASP.Net_SessionID is set in the Session HTTPModule (which 

   97         // has already run), thatwe can't use our own code to see if the cookie was 

   98         // actually sent by the agent with the request using the collection. Check if 

   99         // the given page supports session or not (this tested as reliable indicator 

  100         // if EnableSessionState is true), should not care about a page that does 

  101         // not need session

  102         if (Context.Session != null)

  103         {

  104             //Tested and the IsNewSession is more advanced then simply checking if 

  105             // a cookie is present, it does take into account a session timeout, because 

  106             // I tested a timeout and it did show as a new session

  107             if (Session.IsNewSession)

  108             {

  109                 // If it says it is a new session, but an existing cookie exists, then it must 

  110                 // have timed out (can't use the cookie collection because even on first 

  111                 // request it already contains the cookie (request and response

  112                 // seem to share the collection)

  113                 string szCookieHeader = Request.Headers["Cookie"];

  114                 if ((null != szCookieHeader) && (szCookieHeader.IndexOf("ASP.NET_SessionId") >= 0))

  115                 {

  116                     //string url = "~/Default.aspx?x=" + RedirectMessage("Session Timed out.");

  117                     //Response.Redirect(url);

  118                     Session["TimeoutMessage"] = "Your Session timed out";

  119                     Response.Redirect("~/Default.aspx");

  120                 }

  121             }

  122         }

  123     }

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]