Hi Mike,
So the default setting is true, is that is why setting it true seems to
have
no effect?
Correct.
The forms data then is in the Request object. Is using the Request object
a better solution than setting up the calling object to transfer the data
via
a series of get calls? Or is it just a matter of preference?
I'm having a little trouble understanding this one. Yes, the posted form
data is in the Request object. The Request object is created by parsing an
HTTP Request; in this case, the form POST Request from the Page.
Now, where I'm somewhat fuzzy is with the second part of the question. What
do you mean by "the calling object?" What do you mean by "setting up the
calling object to transfer data via a series of get calls?" Perhaps I can
explain a little bit (?) more of the technical aspect of this and answer
your question without understanding it fully.
The ASP.Net object model works in an HTTP environment. HTTP is a series of
client Requests and server Responses, kind of like a conversation between
client and server. But due to the stateless nature of HTTP, neither the
client nor the server can remember that previous message, or even that a
previous message was sent. Every HTTP Request/Response occurs "in a vacuum,"
so to speak. This is the primary reason why ASP.Net applications are
problematic to write. You want the server to have some memory of the context
of what is being done, in order to behave like an application. The way that
Microsoft has addressed this issue is via a set of mechanisms to emulate
state, and to maintain server state.
State can indeed be maintained on the server, in memory, in a database, via
any number of storage mechanisms. The trick is to associate the state with
each client, as the clients' Requests are not remembered after each Response
is sent. So, Application state, being global to the Application, is not a
problem. But client state is. The way that client state is maintained is
basically two-fold.
One is the use of the Request coming from the client. An HTTP Request can
include a certain amount of header data, QueryString data in the URL, form
data in form fields sent via POST, and any Cookies for that domain stored on
the client. The server can set cookies, which are returned with the
Response, and it can read the Cookies which are always included in the
client Request. Now, some Cookies are persistent, having an expiration
date/time in them, which causes them to be stored on the client's hard
drive. But Cookies without an expiration are referred to as "Session
Cookies." By default, they are stored only in the memory of the browser, and
expire when the browser navigates away from the web site, or closes. Many
browsers do not allow persistent Cookies, but most browsers do allow Session
Cookies. So, the first Request from the client causes the server to create a
memory space for that client, in a Collection stored in the Application,
which is called a Session. The Session is assigned a unique ID, and that ID
is sent as a Session Cookie to the client browser. From there, as long as
the client continues to send Requests, the Cookie makes round trips with
each Request/Response. Since the server is never notified that the client is
no longer there, it waits for 20 minutes for a Request, and if no Request is
received during that interval, it deletes the Session for that client,
freeing up memory on the server.
The other method for maintaining State is to pass data to the client, and
receive it back via Query String or form POST. Hence, you have the PostBack
model. This includes not only the form fields created by the Controls you
put into the page, but several hidden form fields, including a hidden form
field called "ViewState" that keeps track of the state of the Controls when
the last Response was sent to the client. When the user makes changes to the
form fields on the client, the values of these form fields are posted with
the Request, and the server compares them to the ViewState data to see what
has changed, and possibly respond to it.
Events are created by adding some JavaScript client-side event handlers that
put data into a couple of other hidden form fields, and then post the form
to the server. The server-side app looks at these hidden form fields to find
out what client-side events have occurred, and creates real server-side
Events to react to them.
All of this is built into the ASP.Net object model, and though you should be
aware of it, you generally don't have to think much about it; it handles
itself. It is important, though, to understand the object model, as well as
how HTTP works, in order to make intelligent choices about what to code on
the server.
So, now, we have the HTTP Request/Response, and we have 2
indirectly-connected applications, one on the client (the browser and the
HTML document loaded into it), and one on the server. It is the one on the
server that I want to discuss now, in order to hopefully answer your
question. Now, once the Request is received from the client, we are no
longer talking about Pages and Requests, and all that other client-side web
stuff; we are talking about a server application, which behaves on the
server just like any other application. Event though you have a class called
"System.Web.UI.Page," it isn't a "page" at all, or a document even. It is a
class. It is an executable business component. Any other System.Web.UI.Page
class on the server is also not a document, but a business entity in the
application. So, when you use Server.Transfer, you are simply calling on
another class to finish processing. You are transferring execution control
to another class.
Now, the Request object, as I said, is parsed from the HTTP Request received
from the client. It is not the same as the HTTP Request itself, which is
simply a text document. It is a class that contains data and process. The
data has been extracted from the HTTP Request, and the process is executable
code that can manipulate the data. It is the same with the HttpContext. The
HttpContext is a class that contains data and process extracted from the
HTTP Request, and from the web server. HTTP is no loger part of the
equation. The HTTP Request was sent, received from the client, parsed, and
classes were built from it. It then went the way of all flesh, disappearing
into the void. HTTP will not be a part of the equation again until the
server-side application hands off the finished HTML document, as a stream
containing text, to the web server again. At that point, the web server will
create an HTTP Response message to the client.
So, it's best to remember that, although these classes have names, and use
terms that are reminiscent of HTTP, they are not, in fact, doing anything at
all with HTTP. They are simply an application processing data.
Now, how does Response.Redirect work? Simple. Rather than creating a full
HTML document, an HTTP Response with a "302" Status code is formed. The
"302" Status code indicates that a resource has moved temporarily to another
URL, and the Response header contains the other URL to Request. Again,
however, the Page class itself doesn't send the Response. It simply creates
it and hands it off to the web server.
So, on the server-side, there is no such thing as "transfer the data via a
series of get calls" on the server. There is no HTTP operating in the
ASP.Net application. When using Server.Transfer, program execution is simply
transferred to another class.
Now, as to when to use Response.Redirect, and when to use Server.Tranfer,
well, you know of one reason already. The URL of the browser changes to the
new Page URL if you use Response.Redirect. This is useful when you want to
treat the second Page class as if it is really another web page. Rembmber
that on the client, it *is* another web page. Using Server.Transfer, on the
other hand, is useful if you want to treat the HTML output of the second
Page class as if it was indeed part of the first Page, which was requested
by the client.
As for performance issues, yes, there is another Round-trip involved with
Response.Redirect, but there are also any number of Round-trips associated
with the PostBack model. ASP.Net is designed to optimize server resources as
much as possible under this scenario. The only real issue is latency on the
client. But again, a Redirect Response is a very small HTTP message. In
other words, I wouldn't be concerned about it. I would be concerned instead
with which method is most appropriate in terms of how you want the app to
work.
Whew! I hope that helped!
Do you know if that causes any confusion for users? Using Redirect seems
to be a little inefficient?
After reading my explanation, I hope you can see why I said that the
"inefficiency" of using Response.Redirect should not be an issue. In fact,
you have put your finger on the button with this question. How do you want
the client user to perceive the Responses sent by your app?
Think of the client browser as a user interface, and the server-side app as
a set of business objects that interact with it remotely. Your goal, in
terms of the user interface, is to make it user-friendly. If you keep that
in mind, I don't think you'll have any trouble figuring out what to use and
when.
--
HTH,
Kevin Spencer
Microsoft MVP
..Net Developer
You can lead a fish to a bicycle,
but it takes a very long time,
and the bicycle has to *want* to change.