CompilationMode=Never & SessionState - asp.net

It seems that CompilationMode=Never doesn't permit Sessions to be properly wired.
It first complains that the EnbaleSessionState directive is not allowed on this page.
Explicitly assigning the System.Web.SessionState.IRequiresSessionState to the Page [1] avoids the null reference exceptions (around .Session access) but still doesn't persist or wire-up sessions correctly.
Has anyone successfully used ASP.NET Sessions with CompilationMode=Never?
Conceptually, why should these be disjoint??
[1] -
http://msdn.microsoft.com/en-us/library/system.web.ui.compilationmode.aspx

I don't know the exact situation you are in but what you say is correct - Page + IRequiresSessionState = Session Available. Here is what you do. First define a base class for your pages which will receive session state:
public class BasePage : Page, IRequiresSessionState
{
}
Then in your NoCompile Page you do the following declaration:
<%# Page Language="C#" CompilationMode="Never" Inherits="BasePage" %>
Works as expected. Session state is available. Now little more about your second question: "Conceptually, why should these be disjoint??". By default the Page
public class Page : TemplateControl, IHttpHandler
{
}
class doesn't implement IRequiresSessionState and thus have no session state. What ASP.NET does for you is compiling a class for you at runtime through which it provides the session - i.e. if I define a page called Default.aspx, with code behind class that implements Page, nowhere I explicitly implement IRequiresSessionState. But ASP.NET compiles ours Default.aspx UI into a class called:
public class default_aspx : Default, IRequiresSessionState, IHttpHandler
{
}
which now explicitly says that it wants session state to be delivered. This is because "EnbaleSessionState" in the #Page directive is by default set to True. Now when you say that default.aspx is a non compile unit by specifying CompilationMode="Never", then this class is never generated and you never get the Session State, which makes the use of "EnbaleSessionState" not meaningful and thus disabled.

Related

Access function member of base page class?

Currently I'm utilizing a base page class for my website declared like so:
Public Class BasePage
Inherits System.Web.UI.Page
and subsequent pages inherit that using:
Partial Class Default
Inherits BasePage
I have a function in the base page class that I want to be able to use from the pages that inherit the class. The function I have is declared:
Public Function GetSiteVers(ByVal parType As String) As String
When I attempt to call from a page that is inheriting the class:
Me.GetSiteVers("Misc")
I get the error
"GetSiteVers is not a member of Default"
or just
GetSiteVers("Misc")
I get the error:
'GetSiteVers' is not declared. It may be inaccessible due to its protection level.
I've different declarations and Vis Studio's intellisense finds no errors and when I build the page locally I get no compiler errors. Anyone have any ideas or suggestions?
The steps taken to correct this were:
Delete existing Basepage class file from App_code (BasePage.vb)
Reload page that was throwing the error (resuting in an obvious error, but forcing a recompile of the web without the class (clears out cached temp files I assume)
Copied back over BasePage.vb to App_Code
Reloaded offending page and it loaded without error
I'm assuming that this is the fashion in which to clear out any cached/temp files being referred to in the web. Odd way of doing it, but when you don't have complete control of IIS I guess that's the path one has to take.

Why the .aspx inherited IDispose,but .ashx not?

They are all inherited the Interface IHttpHandler,so the asp.net will call they by the same way. But why the aspx page inherited IDispose? Asp.net is how to achieve it?
ASP.NET page is inheriting from the base System.Web.UI.Page class which in turn implements the abstract System.Web.UI.TemplateControl class that inherits from System.Web.UI.Control which implements IDisposable.
In the code, there is the remark for the Dispose() of the Control class:
// Summary:
// Enables a server control to perform final clean up before it is released
// from memory.
That's the reason why .aspx file essentially implements the IDisposable interface.
Now, ASP.NET handler is directly implementing the System.Web.IHttpHandler interface without inheriting any other classes - being independent interface, it does not implement IDisposable - it's up to the programmer to decide whether to add such thing or not.
So your question is, how does the Dispose() code of the aspx (Page) ever get called?
You're making the assumption that ASP.NET framework only sees an IHttpHandler, whether it contains a Page or another implementation. That's almost certainly not true; something needs to call the page's constructor.
You could use a tool like IL Spy to try to find where the different handling is, and what it looks like.

Passing Data Between ASP.net Pages using vb.net

I am writing my very first asp.net application and am trying to use the PreviousPage property to access data between pages. Visual 2010 is giving me an error which I don't understand, so I need some help to understand what I am doing wrong.
I have an application where I will bounce between all the pages using Transfer. That way, from a user perspective there is only ever one url that he sees. This url will be the one that makes him log in to the application (a application controlled function for now) and connect to the database. I therefore have an sqlclient.sqlconnection object that I wish to hand off to the next page called _dbConnection this is a private variable in my page class declared ...
Partial Class Protocol
Inherits System.Web.UI.Page
Private _dbconnection As SqlClient.SqlConnection
Public ReadOnly Property dbConnection As SqlClient.SqlConnection
Get
Return _dbConnection
End Get
End Property
...
Later down the code, in reponse to a click event on a button
Server.Transfer("PSetup.aspx")
In PSetup.aspx I have the following
<%# Page Title="" Language="VB" MasterPageFile="~/MasterPage.master" AutoEventWireup="True" CodeFile="PSetup.aspx.vb" Inherits="PSetup" %>
<%# PreviousPageType VirtualPath="~/Protocol.aspx" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
Which should declare the Protocol class as the previous page
However in PSetup's Page_Load Sub I attempt this
_dbConnection = PreviousPage.dbConnection
where in this use _dbConnection is a private variable in the new page class.
Visual Studio is giving me an error 'dbConnection' is not a member of 'System.Web.UI.Page'
I have read through the documentation about this several times and I just don't understand what I am doing wrong. Could someone help me please.
I guess the first thing you need to understand is that ASP.NET is stateless. That means that no data is "saved" between pages. What the PreviousPage property does is it allows the request information persist through the use of a Transfer method, and the request information will be the GET or POST variables.
IMHO, the best way to do what you desire, is to have a shared public class that is not related to either page, and have a public function for getting the SqlConnection. Remember though, it is stateless, so you will have to create the connection each time.
Another alternative would be to save the dbConnection in the session (which I don't recommend, since it is possible to view the session information).
Otherwise, you can't have a variable persist with information between pages. Thats what is means to be stateless.
ALSO, for PreviousPage, keep in mind that it is creating an instance of System.Web.UI.Page, not an instance of Protocol. That means public properties won't exist from Protocol, only native features of Page will be there.
edit
From msdn
Note
Properties on the source page that are created primarily to expose values for cross-page posting are usually read-only properties. Although the source page can contain public read/write properties, setting a source page property from the target page property generally has no purpose, because the value will not be persisted.
try to make the dbConnection variable as Shared
Partial Class Protocol
Inherits System.Web.UI.Page
Private Shared _dbconnection As SqlClient.SqlConnection
Public Shared ReadOnly Property dbConnection As SqlClient.SqlConnection
Get
Return _dbConnection
End Get
End Property
But I'm not sure if it is a good practice passing data between pages that way

short string representing Viewstate Visible even if view state on each and every control is disabled

I disabled the viewstate on page and each control within it. But I still see short string representing the viewstate in the page source.
I created a page with two controls, one a checkbox and other a texbox. I completely disabled the viewstate for both the controls and the page. But I still see a div rendered which contains the viewstate in the hidden variable:
<div class="aspNetHidden"> <input id="__VIEWSTATE" type="hidden"
value="/wEPDwUKMTcwNTQzMjY4MWQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFG‌​
2N0bDAwJE1haW5Db250ZW50JGNoYm94VGVzdPRq7jJUwzyCcKYfAFB/seRcAvziSp3bKL23H9U7O9sU"
name="__VIEWSTATE"> </div>
Can anyone help in understanding this behaviour of asp.net
1) You must have a server-side form tag () in your ASPX page if you want to use ViewState. A form field is required so the hidden field that contains the ViewState information can post back to the server. And, it must be a server-side form so the ASP.NET page framework can add the hidden field when the page is executed on the server.
2) The page itself saves 20 or so bytes of information into ViewState, which it uses to distribute PostBack data and ViewState values to the correct controls upon postback. So, even if ViewState is disabled for the page or application, you may see a few remaining bytes in ViewState.
3) In cases where the page does not post back, you can eliminate ViewState from a page by omitting the server side tag.
http://msdn.microsoft.com/en-us/library/ms972427.aspx
It's the control state.
If you really want to get rid of viewstate and controlstate you can use this code in the code-behind for the page, or in any class that the code-behind derives from
class MyPage : Page {
private class DummyPageStatePersister : PageStatePersister {
public DummyPageStatePersister(Page p) : base(p) {}
public override void Load() {}
public override void Save() {}
}
private DummyPageStatePersister _PageStatePersister;
protected override PageStatePersister PageStatePersister {
get {
if (_PageStatePersister == null)
_PageStatePersister = new DummyPageStatePersister(this);
return _PageStatePersister;
}
}
// other stuff comes here
}
Be very careful when doing this, though, since you're violating the contract with the controls. MSDN explicitly states that control state is always available. In practice, however, it has worked for me.
Edit:
Since I was downvoted, I like to point out again: Don't do this unless you know exactly what you are doing. In my case, almost the entire application was written in client-side javascript, and on those few occations where postbacks occurred, I always used the Request.Form collection to retrieve the values. Do not use server-side controls for anything but simple rendering if you do this.
No, you can not get rid of View State completely. You will always have a relatively short string representing the page itself even if you turn off the view state on each and every control.
Check State Management (View State).

ASP.NET 2.0 - Parent Page Class not accessible from custom control

1) I've page class
public partial class MyDelivery : System.Web.UI.Page
2) ASCX is in different subfolder
public partial class MyControls_Hello_Bye : System.Web.UI.UserControl
I am unable to access #1 parent page class from control
This problem annoyed me for quite a while. I don't think my solution is perfect, but it sure helps my junior developers in coding. We have a base user control that all user controls inherit and we (like you) we have a base page class that all pages must inherit (team rule). In the user control is a property called ParentForm which is strongly typed to the specific page type that will contain it (the page baseclass if that is variable or unknown at the time).
During the load event of the page, we manually set the Parentform Property of all user controls (we do this in our master page for all master page level controls as well).
protected Page_Load(object sender, System.EventArgs e)
{
this.myControl.ParentForm = this;
this.myControl2.ParentForm = this;
}
This provides immediate access from any user control back to the page and any of its exposed methods. It also provides a standardized (within our team) method of allowing controls to communicate between themselves through an interface in the ParentForm.
Our standard is to perform this assignment manually. For me this was a personnel consideration to make sure developers are aware of the controls they are adding (not setting the ParentForm will cause null reference exceptions if you attempt to access it obviously). If you wanted to perform this setting automagically, you could use the base class's Page_InitComplete event to cycle through any user controls and set the ParentForm to "this" that way.
Being in a different directory would get visual studio to give them different namespaces by default, causing the parent page class not to visible to the control.
Make sure the namespace declarations of both classes are the same, or import the parent page class namespace to the contorl with the using statement.

Resources