views:

514

answers:

4

I have an ASP.NET 3.5 page with a gridview databound to a generic list of objects. The purpose of this page is to show the user a list of items they're responsible for so they can select one and go to the maintenance page to see the details of that item.

I have the "AutoGenerateSelectButton" property set to True. I have no problem when the user immediately selects one of the items (firing the .SelectedIndexchanged event, I do a little processing and Response.Redirect them to the appropriate page).

However, if I wait a few minutes, then hit the Select, I get "Cannot display the webpage" as if I were disconnected from the net. No messages get sent to the application's log file (debugging messages that should indicate the user selected a particular item and that a redirect is about to happen) so there's nothing for me to trap/debug/fix.

I tried going into the web.config and added

"<sessionState timeout="60"></sessionState>"

in hopes that the timeout would go to an hour (users will frequently let the app sit on their screens for quite a while) but that doesn't seem to have worked.

Where else can I look?

Thanks in advance

A: 

I've had a very similar issue. You may hate this answer because it's a little tedious but I programmatically added a button in the Gridview_RowCreated which allows more power.

On page load add a column to the grid.

 If Not IsPostBack Then
        Dim field As New TemplateField
        field.HeaderText = "Maintenance"
        Dim col As DataControlField = field
        GridView.Columns.Add(col)

--Add the link button here

For i = 0 To GridView.Rows.Count - 1
            Dim alinkbutton As New Linkbutton
            GridViewCshr.Rows(i).Cells(3).Controls.Add(alinkbutton )
        Next
 End If

(adding the button to the grid is in the third column but add it whereever you add the new column programmatically)

---Then in GridView_rowcommand

Response.Redirect("url")
Eric
The gridview's .SelectedIndexChanged (when the user picks an item and should then be redirected to the detail page). This also happens when the user tries to sort the gridview (Gridview.Sorting). In the first case, I'm simply determining which row they picked, grab an ID from that row, set a Session variable (that the next page will read) and Response.Redirect them to the new page.
David
Ok. One more Question. Are you programmatically binding data to this grid or did you choose a datasource for your gridview on the form?
Eric
Programmatically. Specifically: grdRequests.DataSource = lstRequests grdRequests.DataBind()lstRequests is a generic list of "Request" objects. The idea is to pick one and go to the maintenance page. But I'm not even hitting the Page.Load when I click on the "Select" (when I've waited long enough - if not, it just happily process the way it should)
David
I edited my answer...Give that a shot.
Eric
I changed the link from the automatically generated "Select" to a real hyperlink with a parameter buried in the URL (e.g. "/?ID=nnn") - and while that helps with linking to the detail page, the column header links (for sorting by column) still lose their mind after a few minutes.
David
A: 

I can see from your web.config extract that you are running your sessionState in process (Default mode). In this mode the session state is effectively kept in memory in the process of the IIS worker process. This means that when the IIS Worker process handling your application is terminated, e.g. because IIS is recycling the application pool, the session state is wiped out.

You can try increasing the idle time out for the worker process ( the default is 20 minutes ) on the application pool configuration.

For IIS6

  1. In IIS Manager, expand the local computer, expand Application Pools, right-click the application pool, and then click Properties.
  2. On the Performance tab, under Idle timeout, deselect the Shutdown worker processes after being idle for check box. -OR-
  3. In the minutes box, type the number of idle minutes (with no processing requests) that you want to elapse before shutting down the idle worker process. The default value is 20 minutes
  4. Click OK.

For IIS7

  1. Open inetmgr
  2. Expand the appropriate server
  3. Click "Application Pools"
  4. Right click the Application Pool Under which your application is running and from the context menu select "Recycling"
  5. Deselect all checkboxes, click "Next" and click "Finish"
  6. Right click the Application Pool Under which your application is running and from the context menu select "Advanced Settings ..."
  7. Under "Process Model" set "Idle Time-Out (minutes)" to some large value
  8. Click "OK"

However, it would be far better to move your session state out of process for long running applications such as yours. It is a fairly simple procedure and will save you lots of session related headaches. The article at http://msdn.microsoft.com/en-us/library/ms178586.aspx will give you a good overview on how to accomplish this.

Peter Stuer
Apparently, the state server process is not running on the target server so that's not an option - at least not in the short term.
David
I eliminated ViewState *only* on the datagrid since that was the biggest piece of 'state' on the page. I already had code compensating for the possibility of losing the databinding between postbacks so this didn't affect things too much. It *appears* to have solved the problem - meaning that somehow, my PC's IIS server could handle a client coming in with a big (600K) viewstate but our 'real' server does something that screws with it after less than 3 minutes. *Smaller* viewstates appear to be unaffected.
David
A: 

Greetings David,

This kind of problems is difficult to be solved by asking online, they need to be examined on-site, so I won't give you an answer, but just some hints:

  • Does this application use authentication and authorization? if so, the authentication cookie may be expiring after leaving the app inactive for a long time, and if you click the "select" button you're redirected to the login page, but the login page itself may be having a problem that causes a redirection loop to occur, which causes most browsers to display the "This page cannot be displayed" message after a couple of runs of the loop. The loop may be caused by other factors, so I suggest tracing your http interactivity using Fiddler, you will know what response the server gives, and why the browser displays the error page.
  • With fiddler attached, I suggest running the app in debug mode, and from the visual studio menu, select Debug>Exceptions, then check all the boxes in the "Thrown" and "User unhandled" columns, this will cause the debugger to break on every exception even they're handled.
  • The last point is irrelevant: I suggest changing the way in which users select from the grid. instead of a "select" link button, place a link with the url of the other page, and pass the id of the selected item as a url parameter. This will save a round trip to the server, and the tiny session storage overhead. In the other page, you must take care that someone won't play with the url parameter to manipulate data he doesn't have permissions to manipulate.
Ashraf Sabry
Yeah, I thought of making a 'simple' link to the detail page and passing the 'id' as a parameter. That's the way the old 'Classic' ASP system does it. But I was hoping to avoid a situation where the user could 'fake' the ID by typing it manually into the address bar - just as a security precaution (one of many already built in). I may be forced to do it whether I want to or not.
David
A: 

Try setting EnableViewStateMac to falseon the page to see if it is related to this.

RichardOD
it seems to have had the effect of changing the number of "Refresh Page" requests required from 2 to 1 in order for the GridView to "reclaim it's mind". It also seems to have allowed the GridView to keep it's mind longer so long as something is happening. In other words, it still "times out" after 4 minutes of inactivity, but if I keep clicking on the column headers (for sorting), I can stretch those few minutes out some.
David
This idea, taken a little further, seems to have sone the trick. I've yet to figure out what's different about the 'production' server but when I also disabled viewstate on the gridview in question (and already had code to re-bind things stored in Session variables between postbacks if needed), suddenly, the gridview didn't lose it's mind after 3 minutes.
David
OK, now you having it working, realise that disabling viewstate MAC can cause security issues- though this is less important if you are in an Intranet scenario. Personally I would look into generating a machine key (read about why first- Google it)- there is a machine key generator here: http://aspnetresources.com/tools/keycreator.aspx
RichardOD
Oh, BTW do you have a Web farm or clustering on the production server?
RichardOD
It's a mostly-Intranet-but-some-outside application. Security is handled via CAC-card access. It's a military installation that has limited access for some outside contractors. No farm or clustering here.
David